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

1.1     ! root        1: /*
        !             2:  *  util.c
        !             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: #include <stdarg.h>
        !            23: 
        !            24: #include "dialog.h"
        !            25: 
        !            26: struct dialog_info dlg;
        !            27: 
        !            28: static void set_mono_theme(void)
        !            29: {
        !            30:        dlg.screen.atr = A_NORMAL;
        !            31:        dlg.shadow.atr = A_NORMAL;
        !            32:        dlg.dialog.atr = A_NORMAL;
        !            33:        dlg.title.atr = A_BOLD;
        !            34:        dlg.border.atr = A_NORMAL;
        !            35:        dlg.button_active.atr = A_REVERSE;
        !            36:        dlg.button_inactive.atr = A_DIM;
        !            37:        dlg.button_key_active.atr = A_REVERSE;
        !            38:        dlg.button_key_inactive.atr = A_BOLD;
        !            39:        dlg.button_label_active.atr = A_REVERSE;
        !            40:        dlg.button_label_inactive.atr = A_NORMAL;
        !            41:        dlg.inputbox.atr = A_NORMAL;
        !            42:        dlg.inputbox_border.atr = A_NORMAL;
        !            43:        dlg.searchbox.atr = A_NORMAL;
        !            44:        dlg.searchbox_title.atr = A_BOLD;
        !            45:        dlg.searchbox_border.atr = A_NORMAL;
        !            46:        dlg.position_indicator.atr = A_BOLD;
        !            47:        dlg.menubox.atr = A_NORMAL;
        !            48:        dlg.menubox_border.atr = A_NORMAL;
        !            49:        dlg.item.atr = A_NORMAL;
        !            50:        dlg.item_selected.atr = A_REVERSE;
        !            51:        dlg.tag.atr = A_BOLD;
        !            52:        dlg.tag_selected.atr = A_REVERSE;
        !            53:        dlg.tag_key.atr = A_BOLD;
        !            54:        dlg.tag_key_selected.atr = A_REVERSE;
        !            55:        dlg.check.atr = A_BOLD;
        !            56:        dlg.check_selected.atr = A_REVERSE;
        !            57:        dlg.uarrow.atr = A_BOLD;
        !            58:        dlg.darrow.atr = A_BOLD;
        !            59: }
        !            60: 
        !            61: #define DLG_COLOR(dialog, f, b, h) \
        !            62: do {                               \
        !            63:        dlg.dialog.fg = (f);       \
        !            64:        dlg.dialog.bg = (b);       \
        !            65:        dlg.dialog.hl = (h);       \
        !            66: } while (0)
        !            67: 
        !            68: static void set_classic_theme(void)
        !            69: {
        !            70:        DLG_COLOR(screen,                COLOR_CYAN,   COLOR_BLUE,   true);
        !            71:        DLG_COLOR(shadow,                COLOR_BLACK,  COLOR_BLACK,  true);
        !            72:        DLG_COLOR(dialog,                COLOR_BLACK,  COLOR_WHITE,  false);
        !            73:        DLG_COLOR(title,                 COLOR_YELLOW, COLOR_WHITE,  true);
        !            74:        DLG_COLOR(border,                COLOR_WHITE,  COLOR_WHITE,  true);
        !            75:        DLG_COLOR(button_active,         COLOR_WHITE,  COLOR_BLUE,   true);
        !            76:        DLG_COLOR(button_inactive,       COLOR_BLACK,  COLOR_WHITE,  false);
        !            77:        DLG_COLOR(button_key_active,     COLOR_WHITE,  COLOR_BLUE,   true);
        !            78:        DLG_COLOR(button_key_inactive,   COLOR_RED,    COLOR_WHITE,  false);
        !            79:        DLG_COLOR(button_label_active,   COLOR_YELLOW, COLOR_BLUE,   true);
        !            80:        DLG_COLOR(button_label_inactive, COLOR_BLACK,  COLOR_WHITE,  true);
        !            81:        DLG_COLOR(inputbox,              COLOR_BLACK,  COLOR_WHITE,  false);
        !            82:        DLG_COLOR(inputbox_border,       COLOR_BLACK,  COLOR_WHITE,  false);
        !            83:        DLG_COLOR(searchbox,             COLOR_BLACK,  COLOR_WHITE,  false);
        !            84:        DLG_COLOR(searchbox_title,       COLOR_YELLOW, COLOR_WHITE,  true);
        !            85:        DLG_COLOR(searchbox_border,      COLOR_WHITE,  COLOR_WHITE,  true);
        !            86:        DLG_COLOR(position_indicator,    COLOR_YELLOW, COLOR_WHITE,  true);
        !            87:        DLG_COLOR(menubox,               COLOR_BLACK,  COLOR_WHITE,  false);
        !            88:        DLG_COLOR(menubox_border,        COLOR_WHITE,  COLOR_WHITE,  true);
        !            89:        DLG_COLOR(item,                  COLOR_BLACK,  COLOR_WHITE,  false);
        !            90:        DLG_COLOR(item_selected,         COLOR_WHITE,  COLOR_BLUE,   true);
        !            91:        DLG_COLOR(tag,                   COLOR_YELLOW, COLOR_WHITE,  true);
        !            92:        DLG_COLOR(tag_selected,          COLOR_YELLOW, COLOR_BLUE,   true);
        !            93:        DLG_COLOR(tag_key,               COLOR_YELLOW, COLOR_WHITE,  true);
        !            94:        DLG_COLOR(tag_key_selected,      COLOR_YELLOW, COLOR_BLUE,   true);
        !            95:        DLG_COLOR(check,                 COLOR_BLACK,  COLOR_WHITE,  false);
        !            96:        DLG_COLOR(check_selected,        COLOR_WHITE,  COLOR_BLUE,   true);
        !            97:        DLG_COLOR(uarrow,                COLOR_GREEN,  COLOR_WHITE,  true);
        !            98:        DLG_COLOR(darrow,                COLOR_GREEN,  COLOR_WHITE,  true);
        !            99: }
        !           100: 
        !           101: static void set_blackbg_theme(void)
        !           102: {
        !           103:        DLG_COLOR(screen, COLOR_RED,   COLOR_BLACK, true);
        !           104:        DLG_COLOR(shadow, COLOR_BLACK, COLOR_BLACK, false);
        !           105:        DLG_COLOR(dialog, COLOR_WHITE, COLOR_BLACK, false);
        !           106:        DLG_COLOR(title,  COLOR_RED,   COLOR_BLACK, false);
        !           107:        DLG_COLOR(border, COLOR_BLACK, COLOR_BLACK, true);
        !           108: 
        !           109:        DLG_COLOR(button_active,         COLOR_YELLOW, COLOR_RED,   false);
        !           110:        DLG_COLOR(button_inactive,       COLOR_YELLOW, COLOR_BLACK, false);
        !           111:        DLG_COLOR(button_key_active,     COLOR_YELLOW, COLOR_RED,   true);
        !           112:        DLG_COLOR(button_key_inactive,   COLOR_RED,    COLOR_BLACK, false);
        !           113:        DLG_COLOR(button_label_active,   COLOR_WHITE,  COLOR_RED,   false);
        !           114:        DLG_COLOR(button_label_inactive, COLOR_BLACK,  COLOR_BLACK, true);
        !           115: 
        !           116:        DLG_COLOR(inputbox,         COLOR_YELLOW, COLOR_BLACK, false);
        !           117:        DLG_COLOR(inputbox_border,  COLOR_YELLOW, COLOR_BLACK, false);
        !           118: 
        !           119:        DLG_COLOR(searchbox,        COLOR_YELLOW, COLOR_BLACK, false);
        !           120:        DLG_COLOR(searchbox_title,  COLOR_YELLOW, COLOR_BLACK, true);
        !           121:        DLG_COLOR(searchbox_border, COLOR_BLACK,  COLOR_BLACK, true);
        !           122: 
        !           123:        DLG_COLOR(position_indicator, COLOR_RED, COLOR_BLACK,  false);
        !           124: 
        !           125:        DLG_COLOR(menubox,          COLOR_YELLOW, COLOR_BLACK, false);
        !           126:        DLG_COLOR(menubox_border,   COLOR_BLACK,  COLOR_BLACK, true);
        !           127: 
        !           128:        DLG_COLOR(item,             COLOR_WHITE, COLOR_BLACK, false);
        !           129:        DLG_COLOR(item_selected,    COLOR_WHITE, COLOR_RED,   false);
        !           130: 
        !           131:        DLG_COLOR(tag,              COLOR_RED,    COLOR_BLACK, false);
        !           132:        DLG_COLOR(tag_selected,     COLOR_YELLOW, COLOR_RED,   true);
        !           133:        DLG_COLOR(tag_key,          COLOR_RED,    COLOR_BLACK, false);
        !           134:        DLG_COLOR(tag_key_selected, COLOR_YELLOW, COLOR_RED,   true);
        !           135: 
        !           136:        DLG_COLOR(check,            COLOR_YELLOW, COLOR_BLACK, false);
        !           137:        DLG_COLOR(check_selected,   COLOR_YELLOW, COLOR_RED,   true);
        !           138: 
        !           139:        DLG_COLOR(uarrow, COLOR_RED, COLOR_BLACK, false);
        !           140:        DLG_COLOR(darrow, COLOR_RED, COLOR_BLACK, false);
        !           141: }
        !           142: 
        !           143: static void set_bluetitle_theme(void)
        !           144: {
        !           145:        set_classic_theme();
        !           146:        DLG_COLOR(title,               COLOR_BLUE,   COLOR_WHITE, true);
        !           147:        DLG_COLOR(button_key_active,   COLOR_YELLOW, COLOR_BLUE,  true);
        !           148:        DLG_COLOR(button_label_active, COLOR_WHITE,  COLOR_BLUE,  true);
        !           149:        DLG_COLOR(searchbox_title,     COLOR_BLUE,   COLOR_WHITE, true);
        !           150:        DLG_COLOR(position_indicator,  COLOR_BLUE,   COLOR_WHITE, true);
        !           151:        DLG_COLOR(tag,                 COLOR_BLUE,   COLOR_WHITE, true);
        !           152:        DLG_COLOR(tag_key,             COLOR_BLUE,   COLOR_WHITE, true);
        !           153: 
        !           154: }
        !           155: 
        !           156: /*
        !           157:  * Select color theme
        !           158:  */
        !           159: static int set_theme(const char *theme)
        !           160: {
        !           161:        int use_color = 1;
        !           162:        if (!theme)
        !           163:                set_bluetitle_theme();
        !           164:        else if (strcmp(theme, "classic") == 0)
        !           165:                set_classic_theme();
        !           166:        else if (strcmp(theme, "bluetitle") == 0)
        !           167:                set_bluetitle_theme();
        !           168:        else if (strcmp(theme, "blackbg") == 0)
        !           169:                set_blackbg_theme();
        !           170:        else if (strcmp(theme, "mono") == 0)
        !           171:                use_color = 0;
        !           172: 
        !           173:        return use_color;
        !           174: }
        !           175: 
        !           176: static void init_one_color(struct dialog_color *color)
        !           177: {
        !           178:        static int pair = 0;
        !           179: 
        !           180:        pair++;
        !           181:        init_pair(pair, color->fg, color->bg);
        !           182:        if (color->hl)
        !           183:                color->atr = A_BOLD | COLOR_PAIR(pair);
        !           184:        else
        !           185:                color->atr = COLOR_PAIR(pair);
        !           186: }
        !           187: 
        !           188: static void init_dialog_colors(void)
        !           189: {
        !           190:        init_one_color(&dlg.screen);
        !           191:        init_one_color(&dlg.shadow);
        !           192:        init_one_color(&dlg.dialog);
        !           193:        init_one_color(&dlg.title);
        !           194:        init_one_color(&dlg.border);
        !           195:        init_one_color(&dlg.button_active);
        !           196:        init_one_color(&dlg.button_inactive);
        !           197:        init_one_color(&dlg.button_key_active);
        !           198:        init_one_color(&dlg.button_key_inactive);
        !           199:        init_one_color(&dlg.button_label_active);
        !           200:        init_one_color(&dlg.button_label_inactive);
        !           201:        init_one_color(&dlg.inputbox);
        !           202:        init_one_color(&dlg.inputbox_border);
        !           203:        init_one_color(&dlg.searchbox);
        !           204:        init_one_color(&dlg.searchbox_title);
        !           205:        init_one_color(&dlg.searchbox_border);
        !           206:        init_one_color(&dlg.position_indicator);
        !           207:        init_one_color(&dlg.menubox);
        !           208:        init_one_color(&dlg.menubox_border);
        !           209:        init_one_color(&dlg.item);
        !           210:        init_one_color(&dlg.item_selected);
        !           211:        init_one_color(&dlg.tag);
        !           212:        init_one_color(&dlg.tag_selected);
        !           213:        init_one_color(&dlg.tag_key);
        !           214:        init_one_color(&dlg.tag_key_selected);
        !           215:        init_one_color(&dlg.check);
        !           216:        init_one_color(&dlg.check_selected);
        !           217:        init_one_color(&dlg.uarrow);
        !           218:        init_one_color(&dlg.darrow);
        !           219: }
        !           220: 
        !           221: /*
        !           222:  * Setup for color display
        !           223:  */
        !           224: static void color_setup(const char *theme)
        !           225: {
        !           226:        int use_color;
        !           227: 
        !           228:        use_color = set_theme(theme);
        !           229:        if (use_color && has_colors()) {
        !           230:                start_color();
        !           231:                init_dialog_colors();
        !           232:        } else
        !           233:                set_mono_theme();
        !           234: }
        !           235: 
        !           236: /*
        !           237:  * Set window to attribute 'attr'
        !           238:  */
        !           239: void attr_clear(WINDOW * win, int height, int width, chtype attr)
        !           240: {
        !           241:        int i, j;
        !           242: 
        !           243:        wattrset(win, attr);
        !           244:        for (i = 0; i < height; i++) {
        !           245:                wmove(win, i, 0);
        !           246:                for (j = 0; j < width; j++)
        !           247:                        waddch(win, ' ');
        !           248:        }
        !           249:        touchwin(win);
        !           250: }
        !           251: 
        !           252: void dialog_clear(void)
        !           253: {
        !           254:        attr_clear(stdscr, LINES, COLS, dlg.screen.atr);
        !           255:        /* Display background title if it exists ... - SLH */
        !           256:        if (dlg.backtitle != NULL) {
        !           257:                int i;
        !           258: 
        !           259:                wattrset(stdscr, dlg.screen.atr);
        !           260:                mvwaddstr(stdscr, 0, 1, (char *)dlg.backtitle);
        !           261:                wmove(stdscr, 1, 1);
        !           262:                for (i = 1; i < COLS - 1; i++)
        !           263:                        waddch(stdscr, ACS_HLINE);
        !           264:        }
        !           265:        wnoutrefresh(stdscr);
        !           266: }
        !           267: 
        !           268: /*
        !           269:  * Do some initialization for dialog
        !           270:  */
        !           271: int init_dialog(const char *backtitle)
        !           272: {
        !           273:        int height, width;
        !           274: 
        !           275:        initscr();              /* Init curses */
        !           276:        getmaxyx(stdscr, height, width);
        !           277:        if (height < 19 || width < 80) {
        !           278:                endwin();
        !           279:                return -ERRDISPLAYTOOSMALL;
        !           280:        }
        !           281: 
        !           282:        dlg.backtitle = backtitle;
        !           283:        color_setup(getenv("MENUCONFIG_COLOR"));
        !           284: 
        !           285:        keypad(stdscr, TRUE);
        !           286:        cbreak();
        !           287:        noecho();
        !           288:        dialog_clear();
        !           289: 
        !           290:        return 0;
        !           291: }
        !           292: 
        !           293: void set_dialog_backtitle(const char *backtitle)
        !           294: {
        !           295:        dlg.backtitle = backtitle;
        !           296: }
        !           297: 
        !           298: /*
        !           299:  * End using dialog functions.
        !           300:  */
        !           301: void end_dialog(int x, int y)
        !           302: {
        !           303:        /* move cursor back to original position */
        !           304:        move(y, x);
        !           305:        refresh();
        !           306:        endwin();
        !           307: }
        !           308: 
        !           309: /* Print the title of the dialog. Center the title and truncate
        !           310:  * tile if wider than dialog (- 2 chars).
        !           311:  **/
        !           312: void print_title(WINDOW *dialog, const char *title, int width)
        !           313: {
        !           314:        if (title) {
        !           315:                int tlen = MIN(width - 2, strlen(title));
        !           316:                wattrset(dialog, dlg.title.atr);
        !           317:                mvwaddch(dialog, 0, (width - tlen) / 2 - 1, ' ');
        !           318:                mvwaddnstr(dialog, 0, (width - tlen)/2, title, tlen);
        !           319:                waddch(dialog, ' ');
        !           320:        }
        !           321: }
        !           322: 
        !           323: /*
        !           324:  * Print a string of text in a window, automatically wrap around to the
        !           325:  * next line if the string is too long to fit on one line. Newline
        !           326:  * characters '\n' are replaced by spaces.  We start on a new line
        !           327:  * if there is no room for at least 4 nonblanks following a double-space.
        !           328:  */
        !           329: void print_autowrap(WINDOW * win, const char *prompt, int width, int y, int x)
        !           330: {
        !           331:        int newl, cur_x, cur_y;
        !           332:        int i, prompt_len, room, wlen;
        !           333:        char tempstr[MAX_LEN + 1], *word, *sp, *sp2;
        !           334: 
        !           335:        strcpy(tempstr, prompt);
        !           336: 
        !           337:        prompt_len = strlen(tempstr);
        !           338: 
        !           339:        /*
        !           340:         * Remove newlines
        !           341:         */
        !           342:        for (i = 0; i < prompt_len; i++) {
        !           343:                if (tempstr[i] == '\n')
        !           344:                        tempstr[i] = ' ';
        !           345:        }
        !           346: 
        !           347:        if (prompt_len <= width - x * 2) {      /* If prompt is short */
        !           348:                wmove(win, y, (width - prompt_len) / 2);
        !           349:                waddstr(win, tempstr);
        !           350:        } else {
        !           351:                cur_x = x;
        !           352:                cur_y = y;
        !           353:                newl = 1;
        !           354:                word = tempstr;
        !           355:                while (word && *word) {
        !           356:                        sp = strchr(word, ' ');
        !           357:                        if (sp)
        !           358:                                *sp++ = 0;
        !           359: 
        !           360:                        /* Wrap to next line if either the word does not fit,
        !           361:                           or it is the first word of a new sentence, and it is
        !           362:                           short, and the next word does not fit. */
        !           363:                        room = width - cur_x;
        !           364:                        wlen = strlen(word);
        !           365:                        if (wlen > room ||
        !           366:                            (newl && wlen < 4 && sp
        !           367:                             && wlen + 1 + strlen(sp) > room
        !           368:                             && (!(sp2 = strchr(sp, ' '))
        !           369:                                 || wlen + 1 + (sp2 - sp) > room))) {
        !           370:                                cur_y++;
        !           371:                                cur_x = x;
        !           372:                        }
        !           373:                        wmove(win, cur_y, cur_x);
        !           374:                        waddstr(win, word);
        !           375:                        getyx(win, cur_y, cur_x);
        !           376:                        cur_x++;
        !           377:                        if (sp && *sp == ' ') {
        !           378:                                cur_x++;        /* double space */
        !           379:                                while (*++sp == ' ') ;
        !           380:                                newl = 1;
        !           381:                        } else
        !           382:                                newl = 0;
        !           383:                        word = sp;
        !           384:                }
        !           385:        }
        !           386: }
        !           387: 
        !           388: /*
        !           389:  * Print a button
        !           390:  */
        !           391: void print_button(WINDOW * win, const char *label, int y, int x, int selected)
        !           392: {
        !           393:        int i, temp;
        !           394: 
        !           395:        wmove(win, y, x);
        !           396:        wattrset(win, selected ? dlg.button_active.atr
        !           397:                 : dlg.button_inactive.atr);
        !           398:        waddstr(win, "<");
        !           399:        temp = strspn(label, " ");
        !           400:        label += temp;
        !           401:        wattrset(win, selected ? dlg.button_label_active.atr
        !           402:                 : dlg.button_label_inactive.atr);
        !           403:        for (i = 0; i < temp; i++)
        !           404:                waddch(win, ' ');
        !           405:        wattrset(win, selected ? dlg.button_key_active.atr
        !           406:                 : dlg.button_key_inactive.atr);
        !           407:        waddch(win, label[0]);
        !           408:        wattrset(win, selected ? dlg.button_label_active.atr
        !           409:                 : dlg.button_label_inactive.atr);
        !           410:        waddstr(win, (char *)label + 1);
        !           411:        wattrset(win, selected ? dlg.button_active.atr
        !           412:                 : dlg.button_inactive.atr);
        !           413:        waddstr(win, ">");
        !           414:        wmove(win, y, x + temp + 1);
        !           415: }
        !           416: 
        !           417: /*
        !           418:  * Draw a rectangular box with line drawing characters
        !           419:  */
        !           420: void
        !           421: draw_box(WINDOW * win, int y, int x, int height, int width,
        !           422:         chtype box, chtype border)
        !           423: {
        !           424:        int i, j;
        !           425: 
        !           426:        wattrset(win, 0);
        !           427:        for (i = 0; i < height; i++) {
        !           428:                wmove(win, y + i, x);
        !           429:                for (j = 0; j < width; j++)
        !           430:                        if (!i && !j)
        !           431:                                waddch(win, border | ACS_ULCORNER);
        !           432:                        else if (i == height - 1 && !j)
        !           433:                                waddch(win, border | ACS_LLCORNER);
        !           434:                        else if (!i && j == width - 1)
        !           435:                                waddch(win, box | ACS_URCORNER);
        !           436:                        else if (i == height - 1 && j == width - 1)
        !           437:                                waddch(win, box | ACS_LRCORNER);
        !           438:                        else if (!i)
        !           439:                                waddch(win, border | ACS_HLINE);
        !           440:                        else if (i == height - 1)
        !           441:                                waddch(win, box | ACS_HLINE);
        !           442:                        else if (!j)
        !           443:                                waddch(win, border | ACS_VLINE);
        !           444:                        else if (j == width - 1)
        !           445:                                waddch(win, box | ACS_VLINE);
        !           446:                        else
        !           447:                                waddch(win, box | ' ');
        !           448:        }
        !           449: }
        !           450: 
        !           451: /*
        !           452:  * Draw shadows along the right and bottom edge to give a more 3D look
        !           453:  * to the boxes
        !           454:  */
        !           455: void draw_shadow(WINDOW * win, int y, int x, int height, int width)
        !           456: {
        !           457:        int i;
        !           458: 
        !           459:        if (has_colors()) {     /* Whether terminal supports color? */
        !           460:                wattrset(win, dlg.shadow.atr);
        !           461:                wmove(win, y + height, x + 2);
        !           462:                for (i = 0; i < width; i++)
        !           463:                        waddch(win, winch(win) & A_CHARTEXT);
        !           464:                for (i = y + 1; i < y + height + 1; i++) {
        !           465:                        wmove(win, i, x + width);
        !           466:                        waddch(win, winch(win) & A_CHARTEXT);
        !           467:                        waddch(win, winch(win) & A_CHARTEXT);
        !           468:                }
        !           469:                wnoutrefresh(win);
        !           470:        }
        !           471: }
        !           472: 
        !           473: /*
        !           474:  *  Return the position of the first alphabetic character in a string.
        !           475:  */
        !           476: int first_alpha(const char *string, const char *exempt)
        !           477: {
        !           478:        int i, in_paren = 0, c;
        !           479: 
        !           480:        for (i = 0; i < strlen(string); i++) {
        !           481:                c = tolower(string[i]);
        !           482: 
        !           483:                if (strchr("<[(", c))
        !           484:                        ++in_paren;
        !           485:                if (strchr(">])", c) && in_paren > 0)
        !           486:                        --in_paren;
        !           487: 
        !           488:                if ((!in_paren) && isalpha(c) && strchr(exempt, c) == 0)
        !           489:                        return i;
        !           490:        }
        !           491: 
        !           492:        return 0;
        !           493: }
        !           494: 
        !           495: /*
        !           496:  * ncurses uses ESC to detect escaped char sequences. This resutl in
        !           497:  * a small timeout before ESC is actually delivered to the application.
        !           498:  * lxdialog suggest <ESC> <ESC> which is correctly translated to two
        !           499:  * times esc. But then we need to ignore the second esc to avoid stepping
        !           500:  * out one menu too much. Filter away all escaped key sequences since
        !           501:  * keypad(FALSE) turn off ncurses support for escape sequences - and thats
        !           502:  * needed to make notimeout() do as expected.
        !           503:  */
        !           504: int on_key_esc(WINDOW *win)
        !           505: {
        !           506:        int key;
        !           507:        int key2;
        !           508:        int key3;
        !           509: 
        !           510:        nodelay(win, TRUE);
        !           511:        keypad(win, FALSE);
        !           512:        key = wgetch(win);
        !           513:        key2 = wgetch(win);
        !           514:        do {
        !           515:                key3 = wgetch(win);
        !           516:        } while (key3 != ERR);
        !           517:        nodelay(win, FALSE);
        !           518:        keypad(win, TRUE);
        !           519:        if (key == KEY_ESC && key2 == ERR)
        !           520:                return KEY_ESC;
        !           521:        else if (key != ERR && key != KEY_ESC && key2 == ERR)
        !           522:                ungetch(key);
        !           523: 
        !           524:        return -1;
        !           525: }
        !           526: 
        !           527: /* redraw screen in new size */
        !           528: int on_key_resize(void)
        !           529: {
        !           530:        dialog_clear();
        !           531:        return KEY_RESIZE;
        !           532: }
        !           533: 
        !           534: struct dialog_list *item_cur;
        !           535: struct dialog_list item_nil;
        !           536: struct dialog_list *item_head;
        !           537: 
        !           538: void item_reset(void)
        !           539: {
        !           540:        struct dialog_list *p, *next;
        !           541: 
        !           542:        for (p = item_head; p; p = next) {
        !           543:                next = p->next;
        !           544:                free(p);
        !           545:        }
        !           546:        item_head = NULL;
        !           547:        item_cur = &item_nil;
        !           548: }
        !           549: 
        !           550: void item_make(const char *fmt, ...)
        !           551: {
        !           552:        va_list ap;
        !           553:        struct dialog_list *p = malloc(sizeof(*p));
        !           554: 
        !           555:        if (item_head)
        !           556:                item_cur->next = p;
        !           557:        else
        !           558:                item_head = p;
        !           559:        item_cur = p;
        !           560:        memset(p, 0, sizeof(*p));
        !           561: 
        !           562:        va_start(ap, fmt);
        !           563:        vsnprintf(item_cur->node.str, sizeof(item_cur->node.str), fmt, ap);
        !           564:        va_end(ap);
        !           565: }
        !           566: 
        !           567: void item_add_str(const char *fmt, ...)
        !           568: {
        !           569:        va_list ap;
        !           570:         size_t avail;
        !           571: 
        !           572:        avail = sizeof(item_cur->node.str) - strlen(item_cur->node.str);
        !           573: 
        !           574:        va_start(ap, fmt);
        !           575:        vsnprintf(item_cur->node.str + strlen(item_cur->node.str),
        !           576:                  avail, fmt, ap);
        !           577:        item_cur->node.str[sizeof(item_cur->node.str) - 1] = '\0';
        !           578:        va_end(ap);
        !           579: }
        !           580: 
        !           581: void item_set_tag(char tag)
        !           582: {
        !           583:        item_cur->node.tag = tag;
        !           584: }
        !           585: void item_set_data(void *ptr)
        !           586: {
        !           587:        item_cur->node.data = ptr;
        !           588: }
        !           589: 
        !           590: void item_set_selected(int val)
        !           591: {
        !           592:        item_cur->node.selected = val;
        !           593: }
        !           594: 
        !           595: int item_activate_selected(void)
        !           596: {
        !           597:        item_foreach()
        !           598:                if (item_is_selected())
        !           599:                        return 1;
        !           600:        return 0;
        !           601: }
        !           602: 
        !           603: void *item_data(void)
        !           604: {
        !           605:        return item_cur->node.data;
        !           606: }
        !           607: 
        !           608: char item_tag(void)
        !           609: {
        !           610:        return item_cur->node.tag;
        !           611: }
        !           612: 
        !           613: int item_count(void)
        !           614: {
        !           615:        int n = 0;
        !           616:        struct dialog_list *p;
        !           617: 
        !           618:        for (p = item_head; p; p = p->next)
        !           619:                n++;
        !           620:        return n;
        !           621: }
        !           622: 
        !           623: void item_set(int n)
        !           624: {
        !           625:        int i = 0;
        !           626:        item_foreach()
        !           627:                if (i++ == n)
        !           628:                        return;
        !           629: }
        !           630: 
        !           631: int item_n(void)
        !           632: {
        !           633:        int n = 0;
        !           634:        struct dialog_list *p;
        !           635: 
        !           636:        for (p = item_head; p; p = p->next) {
        !           637:                if (p == item_cur)
        !           638:                        return n;
        !           639:                n++;
        !           640:        }
        !           641:        return 0;
        !           642: }
        !           643: 
        !           644: const char *item_str(void)
        !           645: {
        !           646:        return item_cur->node.str;
        !           647: }
        !           648: 
        !           649: int item_is_selected(void)
        !           650: {
        !           651:        return (item_cur->node.selected != 0);
        !           652: }
        !           653: 
        !           654: int item_is_tag(char tag)
        !           655: {
        !           656:        return (item_cur->node.tag == tag);
        !           657: }

unix.superglobalmegacorp.com

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