Annotation of qemu/roms/seabios/tools/kconfig/lxdialog/textbox.c, revision 1.1.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.