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

1.1     ! root        1: /*
        !             2:  *  textbox.c -- implements the text 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: #include "dialog.h"
        !            23: 
        !            24: static void back_lines(int n);
        !            25: static void print_page(WINDOW * win, int height, int width);
        !            26: static void print_line(WINDOW * win, int row, int width);
        !            27: static char *get_line(void);
        !            28: static void print_position(WINDOW * win);
        !            29: 
        !            30: static int hscroll;
        !            31: static int begin_reached, end_reached, page_length;
        !            32: static const char *buf;
        !            33: static const char *page;
        !            34: 
        !            35: /*
        !            36:  * refresh window content
        !            37:  */
        !            38: static void refresh_text_box(WINDOW *dialog, WINDOW *box, int boxh, int boxw,
        !            39:                                                          int cur_y, int cur_x)
        !            40: {
        !            41:        print_page(box, boxh, boxw);
        !            42:        print_position(dialog);
        !            43:        wmove(dialog, cur_y, cur_x);    /* Restore cursor position */
        !            44:        wrefresh(dialog);
        !            45: }
        !            46: 
        !            47: 
        !            48: /*
        !            49:  * Display text from a file in a dialog box.
        !            50:  */
        !            51: int dialog_textbox(const char *title, const char *tbuf,
        !            52:                   int initial_height, int initial_width)
        !            53: {
        !            54:        int i, x, y, cur_x, cur_y, key = 0;
        !            55:        int height, width, boxh, boxw;
        !            56:        int passed_end;
        !            57:        WINDOW *dialog, *box;
        !            58: 
        !            59:        begin_reached = 1;
        !            60:        end_reached = 0;
        !            61:        page_length = 0;
        !            62:        hscroll = 0;
        !            63:        buf = tbuf;
        !            64:        page = buf;     /* page is pointer to start of page to be displayed */
        !            65: 
        !            66: do_resize:
        !            67:        getmaxyx(stdscr, height, width);
        !            68:        if (height < 8 || width < 8)
        !            69:                return -ERRDISPLAYTOOSMALL;
        !            70:        if (initial_height != 0)
        !            71:                height = initial_height;
        !            72:        else
        !            73:                if (height > 4)
        !            74:                        height -= 4;
        !            75:                else
        !            76:                        height = 0;
        !            77:        if (initial_width != 0)
        !            78:                width = initial_width;
        !            79:        else
        !            80:                if (width > 5)
        !            81:                        width -= 5;
        !            82:                else
        !            83:                        width = 0;
        !            84: 
        !            85:        /* center dialog box on screen */
        !            86:        x = (COLS - width) / 2;
        !            87:        y = (LINES - height) / 2;
        !            88: 
        !            89:        draw_shadow(stdscr, y, x, height, width);
        !            90: 
        !            91:        dialog = newwin(height, width, y, x);
        !            92:        keypad(dialog, TRUE);
        !            93: 
        !            94:        /* Create window for box region, used for scrolling text */
        !            95:        boxh = height - 4;
        !            96:        boxw = width - 2;
        !            97:        box = subwin(dialog, boxh, boxw, y + 1, x + 1);
        !            98:        wattrset(box, dlg.dialog.atr);
        !            99:        wbkgdset(box, dlg.dialog.atr & A_COLOR);
        !           100: 
        !           101:        keypad(box, TRUE);
        !           102: 
        !           103:        /* register the new window, along with its borders */
        !           104:        draw_box(dialog, 0, 0, height, width,
        !           105:                 dlg.dialog.atr, dlg.border.atr);
        !           106: 
        !           107:        wattrset(dialog, dlg.border.atr);
        !           108:        mvwaddch(dialog, height - 3, 0, ACS_LTEE);
        !           109:        for (i = 0; i < width - 2; i++)
        !           110:                waddch(dialog, ACS_HLINE);
        !           111:        wattrset(dialog, dlg.dialog.atr);
        !           112:        wbkgdset(dialog, dlg.dialog.atr & A_COLOR);
        !           113:        waddch(dialog, ACS_RTEE);
        !           114: 
        !           115:        print_title(dialog, title, width);
        !           116: 
        !           117:        print_button(dialog, gettext(" Exit "), height - 2, width / 2 - 4, TRUE);
        !           118:        wnoutrefresh(dialog);
        !           119:        getyx(dialog, cur_y, cur_x);    /* Save cursor position */
        !           120: 
        !           121:        /* Print first page of text */
        !           122:        attr_clear(box, boxh, boxw, dlg.dialog.atr);
        !           123:        refresh_text_box(dialog, box, boxh, boxw, cur_y, cur_x);
        !           124: 
        !           125:        while ((key != KEY_ESC) && (key != '\n')) {
        !           126:                key = wgetch(dialog);
        !           127:                switch (key) {
        !           128:                case 'E':       /* Exit */
        !           129:                case 'e':
        !           130:                case 'X':
        !           131:                case 'x':
        !           132:                        delwin(box);
        !           133:                        delwin(dialog);
        !           134:                        return 0;
        !           135:                case 'g':       /* First page */
        !           136:                case KEY_HOME:
        !           137:                        if (!begin_reached) {
        !           138:                                begin_reached = 1;
        !           139:                                page = buf;
        !           140:                                refresh_text_box(dialog, box, boxh, boxw,
        !           141:                                                 cur_y, cur_x);
        !           142:                        }
        !           143:                        break;
        !           144:                case 'G':       /* Last page */
        !           145:                case KEY_END:
        !           146: 
        !           147:                        end_reached = 1;
        !           148:                        /* point to last char in buf */
        !           149:                        page = buf + strlen(buf);
        !           150:                        back_lines(boxh);
        !           151:                        refresh_text_box(dialog, box, boxh, boxw,
        !           152:                                         cur_y, cur_x);
        !           153:                        break;
        !           154:                case 'K':       /* Previous line */
        !           155:                case 'k':
        !           156:                case KEY_UP:
        !           157:                        if (!begin_reached) {
        !           158:                                back_lines(page_length + 1);
        !           159: 
        !           160:                                /* We don't call print_page() here but use
        !           161:                                 * scrolling to ensure faster screen update.
        !           162:                                 * However, 'end_reached' and 'page_length'
        !           163:                                 * should still be updated, and 'page' should
        !           164:                                 * point to start of next page. This is done
        !           165:                                 * by calling get_line() in the following
        !           166:                                 * 'for' loop. */
        !           167:                                scrollok(box, TRUE);
        !           168:                                wscrl(box, -1); /* Scroll box region down one line */
        !           169:                                scrollok(box, FALSE);
        !           170:                                page_length = 0;
        !           171:                                passed_end = 0;
        !           172:                                for (i = 0; i < boxh; i++) {
        !           173:                                        if (!i) {
        !           174:                                                /* print first line of page */
        !           175:                                                print_line(box, 0, boxw);
        !           176:                                                wnoutrefresh(box);
        !           177:                                        } else
        !           178:                                                /* Called to update 'end_reached' and 'page' */
        !           179:                                                get_line();
        !           180:                                        if (!passed_end)
        !           181:                                                page_length++;
        !           182:                                        if (end_reached && !passed_end)
        !           183:                                                passed_end = 1;
        !           184:                                }
        !           185: 
        !           186:                                print_position(dialog);
        !           187:                                wmove(dialog, cur_y, cur_x);    /* Restore cursor position */
        !           188:                                wrefresh(dialog);
        !           189:                        }
        !           190:                        break;
        !           191:                case 'B':       /* Previous page */
        !           192:                case 'b':
        !           193:                case KEY_PPAGE:
        !           194:                        if (begin_reached)
        !           195:                                break;
        !           196:                        back_lines(page_length + boxh);
        !           197:                        refresh_text_box(dialog, box, boxh, boxw,
        !           198:                                         cur_y, cur_x);
        !           199:                        break;
        !           200:                case 'J':       /* Next line */
        !           201:                case 'j':
        !           202:                case KEY_DOWN:
        !           203:                        if (!end_reached) {
        !           204:                                begin_reached = 0;
        !           205:                                scrollok(box, TRUE);
        !           206:                                scroll(box);    /* Scroll box region up one line */
        !           207:                                scrollok(box, FALSE);
        !           208:                                print_line(box, boxh - 1, boxw);
        !           209:                                wnoutrefresh(box);
        !           210:                                print_position(dialog);
        !           211:                                wmove(dialog, cur_y, cur_x);    /* Restore cursor position */
        !           212:                                wrefresh(dialog);
        !           213:                        }
        !           214:                        break;
        !           215:                case KEY_NPAGE: /* Next page */
        !           216:                case ' ':
        !           217:                        if (end_reached)
        !           218:                                break;
        !           219: 
        !           220:                        begin_reached = 0;
        !           221:                        refresh_text_box(dialog, box, boxh, boxw,
        !           222:                                         cur_y, cur_x);
        !           223:                        break;
        !           224:                case '0':       /* Beginning of line */
        !           225:                case 'H':       /* Scroll left */
        !           226:                case 'h':
        !           227:                case KEY_LEFT:
        !           228:                        if (hscroll <= 0)
        !           229:                                break;
        !           230: 
        !           231:                        if (key == '0')
        !           232:                                hscroll = 0;
        !           233:                        else
        !           234:                                hscroll--;
        !           235:                        /* Reprint current page to scroll horizontally */
        !           236:                        back_lines(page_length);
        !           237:                        refresh_text_box(dialog, box, boxh, boxw,
        !           238:                                         cur_y, cur_x);
        !           239:                        break;
        !           240:                case 'L':       /* Scroll right */
        !           241:                case 'l':
        !           242:                case KEY_RIGHT:
        !           243:                        if (hscroll >= MAX_LEN)
        !           244:                                break;
        !           245:                        hscroll++;
        !           246:                        /* Reprint current page to scroll horizontally */
        !           247:                        back_lines(page_length);
        !           248:                        refresh_text_box(dialog, box, boxh, boxw,
        !           249:                                         cur_y, cur_x);
        !           250:                        break;
        !           251:                case KEY_ESC:
        !           252:                        key = on_key_esc(dialog);
        !           253:                        break;
        !           254:                case KEY_RESIZE:
        !           255:                        back_lines(height);
        !           256:                        delwin(box);
        !           257:                        delwin(dialog);
        !           258:                        on_key_resize();
        !           259:                        goto do_resize;
        !           260:                }
        !           261:        }
        !           262:        delwin(box);
        !           263:        delwin(dialog);
        !           264:        return key;             /* ESC pressed */
        !           265: }
        !           266: 
        !           267: /*
        !           268:  * Go back 'n' lines in text. Called by dialog_textbox().
        !           269:  * 'page' will be updated to point to the desired line in 'buf'.
        !           270:  */
        !           271: static void back_lines(int n)
        !           272: {
        !           273:        int i;
        !           274: 
        !           275:        begin_reached = 0;
        !           276:        /* Go back 'n' lines */
        !           277:        for (i = 0; i < n; i++) {
        !           278:                if (*page == '\0') {
        !           279:                        if (end_reached) {
        !           280:                                end_reached = 0;
        !           281:                                continue;
        !           282:                        }
        !           283:                }
        !           284:                if (page == buf) {
        !           285:                        begin_reached = 1;
        !           286:                        return;
        !           287:                }
        !           288:                page--;
        !           289:                do {
        !           290:                        if (page == buf) {
        !           291:                                begin_reached = 1;
        !           292:                                return;
        !           293:                        }
        !           294:                        page--;
        !           295:                } while (*page != '\n');
        !           296:                page++;
        !           297:        }
        !           298: }
        !           299: 
        !           300: /*
        !           301:  * Print a new page of text. Called by dialog_textbox().
        !           302:  */
        !           303: static void print_page(WINDOW * win, int height, int width)
        !           304: {
        !           305:        int i, passed_end = 0;
        !           306: 
        !           307:        page_length = 0;
        !           308:        for (i = 0; i < height; i++) {
        !           309:                print_line(win, i, width);
        !           310:                if (!passed_end)
        !           311:                        page_length++;
        !           312:                if (end_reached && !passed_end)
        !           313:                        passed_end = 1;
        !           314:        }
        !           315:        wnoutrefresh(win);
        !           316: }
        !           317: 
        !           318: /*
        !           319:  * Print a new line of text. Called by dialog_textbox() and print_page().
        !           320:  */
        !           321: static void print_line(WINDOW * win, int row, int width)
        !           322: {
        !           323:        int y, x;
        !           324:        char *line;
        !           325: 
        !           326:        line = get_line();
        !           327:        line += MIN(strlen(line), hscroll);     /* Scroll horizontally */
        !           328:        wmove(win, row, 0);     /* move cursor to correct line */
        !           329:        waddch(win, ' ');
        !           330:        waddnstr(win, line, MIN(strlen(line), width - 2));
        !           331: 
        !           332:        getyx(win, y, x);
        !           333:        /* Clear 'residue' of previous line */
        !           334: #if OLD_NCURSES
        !           335:        {
        !           336:                int i;
        !           337:                for (i = 0; i < width - x; i++)
        !           338:                        waddch(win, ' ');
        !           339:        }
        !           340: #else
        !           341:        wclrtoeol(win);
        !           342: #endif
        !           343: }
        !           344: 
        !           345: /*
        !           346:  * Return current line of text. Called by dialog_textbox() and print_line().
        !           347:  * 'page' should point to start of current line before calling, and will be
        !           348:  * updated to point to start of next line.
        !           349:  */
        !           350: static char *get_line(void)
        !           351: {
        !           352:        int i = 0;
        !           353:        static char line[MAX_LEN + 1];
        !           354: 
        !           355:        end_reached = 0;
        !           356:        while (*page != '\n') {
        !           357:                if (*page == '\0') {
        !           358:                        if (!end_reached) {
        !           359:                                end_reached = 1;
        !           360:                                break;
        !           361:                        }
        !           362:                } else if (i < MAX_LEN)
        !           363:                        line[i++] = *(page++);
        !           364:                else {
        !           365:                        /* Truncate lines longer than MAX_LEN characters */
        !           366:                        if (i == MAX_LEN)
        !           367:                                line[i++] = '\0';
        !           368:                        page++;
        !           369:                }
        !           370:        }
        !           371:        if (i <= MAX_LEN)
        !           372:                line[i] = '\0';
        !           373:        if (!end_reached)
        !           374:                page++;         /* move pass '\n' */
        !           375: 
        !           376:        return line;
        !           377: }
        !           378: 
        !           379: /*
        !           380:  * Print current position
        !           381:  */
        !           382: static void print_position(WINDOW * win)
        !           383: {
        !           384:        int percent;
        !           385: 
        !           386:        wattrset(win, dlg.position_indicator.atr);
        !           387:        wbkgdset(win, dlg.position_indicator.atr & A_COLOR);
        !           388:        percent = (page - buf) * 100 / strlen(buf);
        !           389:        wmove(win, getmaxy(win) - 3, getmaxx(win) - 9);
        !           390:        wprintw(win, "(%3d%%)", percent);
        !           391: }

unix.superglobalmegacorp.com

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