xref: /netbsd-src/lib/libcurses/EXAMPLES/view.c (revision e124de36d8a3bb2fd90b77ec25eb7736f29ee44d)
117c16404Sblymn /*
217c16404Sblymn  * view.c -- a silly little viewer program
317c16404Sblymn  *
417c16404Sblymn  * written by Eric S. Raymond <esr@snark.thyrsus.com> December 1994
517c16404Sblymn  * to test the scrolling code in ncurses.
617c16404Sblymn  *
717c16404Sblymn  * modified by Thomas Dickey <dickey@clark.net> July 1995 to demonstrate
817c16404Sblymn  * the use of 'resizeterm()', and May 2000 to illustrate wide-character
917c16404Sblymn  * handling.
1017c16404Sblymn  *
1117c16404Sblymn  * Takes a filename argument.  It's a simple file-viewer with various
1217c16404Sblymn  * scroll-up and scroll-down commands.
1317c16404Sblymn  *
1417c16404Sblymn  * n	-- scroll one line forward
1517c16404Sblymn  * p	-- scroll one line back
1617c16404Sblymn  *
1717c16404Sblymn  * Either command accepts a numeric prefix interpreted as a repeat count.
1817c16404Sblymn  * Thus, typing `5n' should scroll forward 5 lines in the file.
1917c16404Sblymn  *
2017c16404Sblymn  * The way you can tell this is working OK is that, in the trace file,
2117c16404Sblymn  * there should be one scroll operation plus a small number of line
2217c16404Sblymn  * updates, as opposed to a whole-page update.  This means the physical
2317c16404Sblymn  * scroll operation worked, and the refresh() code only had to do a
2417c16404Sblymn  * partial repaint.
2517c16404Sblymn  *
26*e124de36Sblymn  * $Id: view.c,v 1.2 2007/05/28 15:01:58 blymn Exp $
2717c16404Sblymn  */
2817c16404Sblymn 
2917c16404Sblymn #include <stdlib.h>
3017c16404Sblymn #include <string.h>
3117c16404Sblymn #include <sys/types.h>
3217c16404Sblymn #include <signal.h>
3317c16404Sblymn #ifdef NCURSES
3417c16404Sblymn #define _XOPEN_SOURCE_EXTENDED
3517c16404Sblymn #include <ncurses.h>
3617c16404Sblymn #include <term.h>
3717c16404Sblymn #else
3817c16404Sblymn #include <curses.h>
3917c16404Sblymn #endif /* NCURSES */
4017c16404Sblymn #include <locale.h>
4117c16404Sblymn #include <assert.h>
4217c16404Sblymn #include <ctype.h>
4317c16404Sblymn #include <termios.h>
4417c16404Sblymn #include <util.h>
4517c16404Sblymn #include <unistd.h>
4617c16404Sblymn #ifdef HAVE_WCHAR
4717c16404Sblymn #include <wchar.h>
4817c16404Sblymn #endif /* HAVE_WCHAR */
4917c16404Sblymn #ifdef DEBUG
5017c16404Sblymn #include <syslog.h>
5117c16404Sblymn #endif /* DEBUG */
5217c16404Sblymn 
5317c16404Sblymn #define UChar(c)    ((unsigned char)(c))
5417c16404Sblymn #define SIZEOF(table)	(sizeof(table)/sizeof(table[0]))
5517c16404Sblymn #define typeMalloc(type,n) (type *) malloc((n) * sizeof(type))
5617c16404Sblymn 
5717c16404Sblymn #define my_pair 1
5817c16404Sblymn 
5917c16404Sblymn #undef CURSES_CH_T
6017c16404Sblymn #ifdef HAVE_WCHAR
6117c16404Sblymn #define CURSES_CH_T cchar_t
6217c16404Sblymn #else
6317c16404Sblymn #define CURSES_CH_T chtype
6417c16404Sblymn #endif /* HAVE_WCHAR */
6517c16404Sblymn 
6617c16404Sblymn static void finish(int sig);
6717c16404Sblymn static void show_all(const char *tag);
6817c16404Sblymn 
6917c16404Sblymn static int shift = 0;
7017c16404Sblymn static bool try_color = FALSE;
7117c16404Sblymn 
7217c16404Sblymn static char *fname;
7317c16404Sblymn static CURSES_CH_T **my_lines;
7417c16404Sblymn static CURSES_CH_T **lptr;
75*e124de36Sblymn static unsigned num_lines;
7617c16404Sblymn 
usage(void)7717c16404Sblymn static void usage(void)
7817c16404Sblymn {
7917c16404Sblymn     static const char *msg[] = {
8017c16404Sblymn 	    "Usage: view [options] file"
8117c16404Sblymn 	    ,""
8217c16404Sblymn 	    ,"Options:"
8317c16404Sblymn 	    ," -c       use color if terminal supports it"
8417c16404Sblymn 	    ," -i       ignore INT, QUIT, TERM signals"
8517c16404Sblymn 	    ," -n NUM   specify maximum number of lines (default 1000)"
8617c16404Sblymn #if defined(KEY_RESIZE)
8717c16404Sblymn 	    ," -r       use old-style sigwinch handler rather than KEY_RESIZE"
8817c16404Sblymn #endif
8917c16404Sblymn #ifdef TRACE
9017c16404Sblymn 	    ," -t       trace screen updates"
9117c16404Sblymn 	    ," -T NUM   specify trace mask"
9217c16404Sblymn #endif
9317c16404Sblymn     };
9417c16404Sblymn     size_t n;
9517c16404Sblymn     for (n = 0; n < SIZEOF(msg); n++)
9617c16404Sblymn 	    fprintf(stderr, "%s\n", msg[n]);
9717c16404Sblymn     exit( 1 );
9817c16404Sblymn }
9917c16404Sblymn 
ch_len(CURSES_CH_T * src)10017c16404Sblymn static int ch_len(CURSES_CH_T * src)
10117c16404Sblymn {
10217c16404Sblymn     int result = 0;
10317c16404Sblymn 
10417c16404Sblymn #ifdef HAVE_WCHAR
10517c16404Sblymn     while (getcchar(src++, NULL, NULL, NULL, NULL) > 0)
10617c16404Sblymn 	    result++;
10717c16404Sblymn #else
10817c16404Sblymn     while (*src++)
10917c16404Sblymn 	result++;
11017c16404Sblymn #endif
11117c16404Sblymn     return result;
11217c16404Sblymn }
11317c16404Sblymn 
11417c16404Sblymn /*
11517c16404Sblymn  * Allocate a string into an array of chtype's.  If UTF-8 mode is
11617c16404Sblymn  * active, translate the string accordingly.
11717c16404Sblymn  */
ch_dup(char * src)11817c16404Sblymn static CURSES_CH_T * ch_dup(char *src)
11917c16404Sblymn {
12017c16404Sblymn     unsigned len = strlen(src);
12117c16404Sblymn     CURSES_CH_T *dst = typeMalloc(CURSES_CH_T, len + 1);
12217c16404Sblymn     unsigned j, k;
12317c16404Sblymn #ifdef HAVE_WCHAR
12417c16404Sblymn     wchar_t wstr[CCHARW_MAX + 1];
12517c16404Sblymn     wchar_t wch;
12617c16404Sblymn     int l = 0;
12717c16404Sblymn     mbstate_t state;
12817c16404Sblymn     size_t rc;
12917c16404Sblymn     int width;
13017c16404Sblymn #endif
13117c16404Sblymn 
13217c16404Sblymn #ifdef HAVE_WCHAR
13317c16404Sblymn     mbrtowc( NULL, NULL, 1, &state );
13417c16404Sblymn #endif
13517c16404Sblymn     for (j = k = 0; j < len; j++) {
13617c16404Sblymn #ifdef HAVE_WCHAR
13717c16404Sblymn 	    rc = mbrtowc(&wch, src + j, len - j, &state);
13817c16404Sblymn #ifdef DEBUG
13917c16404Sblymn         syslog( LOG_INFO, "[ch_dup]mbrtowc() returns %d", rc );
14017c16404Sblymn #endif /* DEBUG */
14117c16404Sblymn 	    if (rc == (size_t) -1 || rc == (size_t) -2)
14217c16404Sblymn 	        break;
14317c16404Sblymn 	    j += rc - 1;
14417c16404Sblymn 	    if ((width = wcwidth(wch)) < 0)
14517c16404Sblymn 	        break;
14617c16404Sblymn 	    if ((width > 0 && l > 0) || l == CCHARW_MAX) {
14717c16404Sblymn 	        wstr[l] = L'\0';
14817c16404Sblymn 	        l = 0;
14917c16404Sblymn 	        if (setcchar(dst + k, wstr, 0, 0, NULL) != OK)
15017c16404Sblymn 		        break;
15117c16404Sblymn 	        ++k;
15217c16404Sblymn 	    }
15317c16404Sblymn 	    if (width == 0 && l == 0)
15417c16404Sblymn 	        wstr[l++] = L' ';
15517c16404Sblymn 	    wstr[l++] = wch;
15617c16404Sblymn #ifdef DEBUG
15717c16404Sblymn         syslog( LOG_INFO, "[ch_dup]wch=%x", wch );
15817c16404Sblymn #endif /* DEBUG */
15917c16404Sblymn #else
16017c16404Sblymn 	    dst[k++] = src[j];
16117c16404Sblymn #endif
16217c16404Sblymn     }
16317c16404Sblymn #ifdef HAVE_WCHAR
16417c16404Sblymn     if (l > 0) {
16517c16404Sblymn 	    wstr[l] = L'\0';
16617c16404Sblymn 	    if (setcchar(dst + k, wstr, 0, 0, NULL) == OK)
16717c16404Sblymn 	        ++k;
16817c16404Sblymn     }
16917c16404Sblymn     setcchar(dst + k, L"", 0, 0, NULL);
17017c16404Sblymn #else
17117c16404Sblymn     dst[k] = 0;
17217c16404Sblymn #endif
17317c16404Sblymn     return dst;
17417c16404Sblymn }
17517c16404Sblymn 
main(int argc,char * argv[])17617c16404Sblymn int main(int argc, char *argv[])
17717c16404Sblymn {
17817c16404Sblymn     int MAXLINES = 1000;
17917c16404Sblymn     FILE *fp;
18017c16404Sblymn     char buf[BUFSIZ];
18117c16404Sblymn     int i;
18217c16404Sblymn     int my_delay = 0;
18317c16404Sblymn     CURSES_CH_T **olptr;
18417c16404Sblymn     int length = 0;
18517c16404Sblymn     int value = 0;
18617c16404Sblymn     bool done = FALSE;
18717c16404Sblymn     bool got_number = FALSE;
18817c16404Sblymn     const char *my_label = "Input";
18917c16404Sblymn #ifdef HAVE_WCHAR
19017c16404Sblymn     cchar_t icc;
19117c16404Sblymn #endif /* HAVE_WCHAR */
19217c16404Sblymn 
19317c16404Sblymn     setlocale(LC_ALL, "");
19417c16404Sblymn 
19517c16404Sblymn     (void) signal(SIGINT, finish);	/* arrange interrupts to terminate */
19617c16404Sblymn 
19717c16404Sblymn     while ((i = getopt(argc, argv, "cin:rtT:")) != EOF) {
19817c16404Sblymn 	    switch (i) {
19917c16404Sblymn 	        case 'c':
20017c16404Sblymn 	            try_color = TRUE;
20117c16404Sblymn 	            break;
20217c16404Sblymn 	        case 'i':
20317c16404Sblymn 	            signal(SIGINT, SIG_IGN);
20417c16404Sblymn 	            signal(SIGQUIT, SIG_IGN);
20517c16404Sblymn 	            signal(SIGTERM, SIG_IGN);
20617c16404Sblymn 	            break;
20717c16404Sblymn 	        case 'n':
20817c16404Sblymn 	            if ((MAXLINES = atoi(optarg)) < 1)
20917c16404Sblymn 		        usage();
21017c16404Sblymn 	            break;
21117c16404Sblymn #ifdef TRACE
21217c16404Sblymn 	        case 'T':
21317c16404Sblymn 	            trace(atoi(optarg));
21417c16404Sblymn 	            break;
21517c16404Sblymn 	        case 't':
21617c16404Sblymn 	            trace(TRACE_CALLS);
21717c16404Sblymn 	            break;
21817c16404Sblymn #endif
21917c16404Sblymn 	        default:
22017c16404Sblymn 	            usage();
22117c16404Sblymn 	    }
22217c16404Sblymn     }
22317c16404Sblymn     if (optind + 1 != argc)
22417c16404Sblymn 	    usage();
22517c16404Sblymn 
22617c16404Sblymn     if ((my_lines = typeMalloc(CURSES_CH_T *, MAXLINES + 2)) == 0)
22717c16404Sblymn 	    usage();
22817c16404Sblymn 
22917c16404Sblymn     fname = argv[optind];
23017c16404Sblymn     if ((fp = fopen(fname, "r")) == 0) {
23117c16404Sblymn 	    perror(fname);
23217c16404Sblymn 	    exit( 1 );
23317c16404Sblymn     }
23417c16404Sblymn 
23517c16404Sblymn     /* slurp the file */
236*e124de36Sblymn     num_lines = 0;
23717c16404Sblymn     for (lptr = &my_lines[0]; (lptr - my_lines) < MAXLINES; lptr++) {
23817c16404Sblymn 	    char temp[BUFSIZ], *s, *d;
23917c16404Sblymn 	    int col;
24017c16404Sblymn 
24117c16404Sblymn 	    if (fgets(buf, sizeof(buf), fp) == 0)
24217c16404Sblymn 	        break;
24317c16404Sblymn 
24417c16404Sblymn 	    /* convert tabs so that shift will work properly */
24517c16404Sblymn 	    for (s = buf, d = temp, col = 0; (*d = *s) != '\0'; s++) {
24617c16404Sblymn 	        if (*d == '\n') {
24717c16404Sblymn 		        *d = '\0';
24817c16404Sblymn 		        break;
24917c16404Sblymn 	        } else if (*d == '\t') {
25017c16404Sblymn 		        col = (col | 7) + 1;
25117c16404Sblymn 		        while ((d - temp) != col)
25217c16404Sblymn 		            *d++ = ' ';
25317c16404Sblymn 	        } else
25417c16404Sblymn #ifdef HAVE_WCHAR
25517c16404Sblymn 		        col++, d++;
25617c16404Sblymn #else
25717c16404Sblymn 	            if (isprint(UChar(*d))) {
25817c16404Sblymn 		            col++;
25917c16404Sblymn 		            d++;
26017c16404Sblymn 	            } else {
26117c16404Sblymn 		            sprintf(d, "\\%03o", UChar(*s));
26217c16404Sblymn 		            d += strlen(d);
26317c16404Sblymn 		            col = (d - temp);
26417c16404Sblymn 	            }
26517c16404Sblymn #endif
26617c16404Sblymn 	    }
26717c16404Sblymn 	    *lptr = ch_dup(temp);
268*e124de36Sblymn 	    num_lines++;
26917c16404Sblymn     }
27017c16404Sblymn     (void) fclose(fp);
27117c16404Sblymn     length = lptr - my_lines;
27217c16404Sblymn 
27317c16404Sblymn     (void) initscr();		/* initialize the curses library */
27417c16404Sblymn     keypad(stdscr, TRUE);	/* enable keyboard mapping */
27517c16404Sblymn     (void) nonl();	 /* tell curses not to do NL->CR/NL on output */
27617c16404Sblymn     (void) cbreak(); /* take input chars one at a time, no wait for \n */
27717c16404Sblymn     (void) noecho();		/* don't echo input */
27817c16404Sblymn     nodelay(stdscr, TRUE);
27917c16404Sblymn     idlok(stdscr, TRUE);	/* allow use of insert/delete line */
28017c16404Sblymn 
28117c16404Sblymn     if (try_color) {
28217c16404Sblymn 	    if (has_colors()) {
28317c16404Sblymn 	        start_color();
28417c16404Sblymn 	        init_pair(my_pair, COLOR_WHITE, COLOR_BLUE);
28517c16404Sblymn 	        bkgd(COLOR_PAIR(my_pair));
28617c16404Sblymn 	    } else {
28717c16404Sblymn 	        try_color = FALSE;
28817c16404Sblymn 	    }
28917c16404Sblymn     }
29017c16404Sblymn 
29117c16404Sblymn     lptr = my_lines;
29217c16404Sblymn     while (!done) {
29317c16404Sblymn 	    int n;
29417c16404Sblymn #ifdef HAVE_WCHAR
29517c16404Sblymn         wint_t c = 0;
29617c16404Sblymn         int ret;
29717c16404Sblymn #else
29817c16404Sblymn         int c = 0;
29917c16404Sblymn #endif /* HAVE_WCHAR */
30017c16404Sblymn 
30117c16404Sblymn 	    if (!got_number)
30217c16404Sblymn 	        show_all(my_label);
30317c16404Sblymn 
30417c16404Sblymn 	    n = 0;
30517c16404Sblymn 	    for (;;) {
30617c16404Sblymn             c = 0;
30717c16404Sblymn #ifdef HAVE_WCHAR
30817c16404Sblymn             ret = get_wch( &c );
30917c16404Sblymn             if ( ret == ERR ) {
31017c16404Sblymn 	            if (!my_delay)
31117c16404Sblymn 		            napms(50);
31217c16404Sblymn                 continue;
31317c16404Sblymn             }
31417c16404Sblymn #ifdef DEBUG
31517c16404Sblymn             else if ( ret == KEY_CODE_YES )
31617c16404Sblymn                 syslog( LOG_INFO, "[main]Func key(%x)", c );
31717c16404Sblymn             else
31817c16404Sblymn                 syslog( LOG_INFO, "[main]c=%x", c );
31917c16404Sblymn #endif /* DEBUG */
32017c16404Sblymn #else
32117c16404Sblymn 	        c = getch();
32217c16404Sblymn #ifdef DEBUG
32317c16404Sblymn             syslog( LOG_INFO, "[main]c='%c'", c );
32417c16404Sblymn #endif /* DEBUG */
32517c16404Sblymn #endif /* HAVE_WCHAR */
32617c16404Sblymn 	        if ((c < 127) && isdigit(c)) {
32717c16404Sblymn 		        if (!got_number) {
32817c16404Sblymn 		            mvprintw(0, 0, "Count: ");
32917c16404Sblymn 		            clrtoeol();
33017c16404Sblymn 		        }
33117c16404Sblymn 		        addch(c);
33217c16404Sblymn 		        value = 10 * value + (c - '0');
33317c16404Sblymn 		        got_number = TRUE;
33417c16404Sblymn 	        } else
33517c16404Sblymn 		        break;
33617c16404Sblymn 	    }
33717c16404Sblymn 	    if (got_number && value) {
33817c16404Sblymn 	        n = value;
33917c16404Sblymn 	    } else {
34017c16404Sblymn 	        n = 1;
34117c16404Sblymn 	    }
34217c16404Sblymn 
34317c16404Sblymn #ifdef HAVE_WCHAR
34417c16404Sblymn 	    if (ret != ERR)
34517c16404Sblymn             my_label = key_name( c );
34617c16404Sblymn         else
34717c16404Sblymn 	        if (!my_delay)
34817c16404Sblymn 		        napms(50);
34917c16404Sblymn #else
35017c16404Sblymn 	    if (c != ERR)
35117c16404Sblymn 	        my_label = keyname(c);
35217c16404Sblymn #endif /* HAVE_WCHAR */
35317c16404Sblymn 	    switch (c) {
35417c16404Sblymn 	        case KEY_DOWN:
35517c16404Sblymn #ifdef HAVE_WCHAR
35617c16404Sblymn             case L'n':
35717c16404Sblymn #else
35817c16404Sblymn 	        case 'n':
35917c16404Sblymn #endif /* HAVE_WCHAR */
36017c16404Sblymn 	            olptr = lptr;
36117c16404Sblymn 	            for (i = 0; i < n; i++)
36217c16404Sblymn 		            if ((lptr - my_lines) < (length - LINES + 1))
36317c16404Sblymn 		                lptr++;
36417c16404Sblymn 		            else
36517c16404Sblymn 		                break;
36617c16404Sblymn 	            wscrl(stdscr, lptr - olptr);
36717c16404Sblymn 	            break;
36817c16404Sblymn 
36917c16404Sblymn 	        case KEY_UP:
37017c16404Sblymn #ifdef HAVE_WCHAR
37117c16404Sblymn             case L'p':
37217c16404Sblymn #else
37317c16404Sblymn 	        case 'p':
37417c16404Sblymn #endif /* HAVE_WCHAR */
37517c16404Sblymn 	            olptr = lptr;
37617c16404Sblymn 	            for (i = 0; i < n; i++)
37717c16404Sblymn 		            if (lptr > my_lines)
37817c16404Sblymn 		                lptr--;
37917c16404Sblymn 		            else
38017c16404Sblymn 		                break;
38117c16404Sblymn 	            wscrl(stdscr, lptr - olptr);
38217c16404Sblymn 	            break;
38317c16404Sblymn 
38417c16404Sblymn #ifdef HAVE_WCHAR
38517c16404Sblymn             case L'h':
38617c16404Sblymn #else
38717c16404Sblymn 	        case 'h':
38817c16404Sblymn #endif /* HAVE_WCHAR */
38917c16404Sblymn 	        case KEY_HOME:
39017c16404Sblymn 	            lptr = my_lines;
39117c16404Sblymn 	            break;
39217c16404Sblymn 
39317c16404Sblymn #ifdef HAVE_WCHAR
39417c16404Sblymn             case L'e':
39517c16404Sblymn #else
39617c16404Sblymn 	        case 'e':
39717c16404Sblymn #endif /* HAVE_WCHAR */
39817c16404Sblymn 	        case KEY_END:
39917c16404Sblymn 	            if (length > LINES)
40017c16404Sblymn 		            lptr = my_lines + length - LINES + 1;
40117c16404Sblymn 	            else
40217c16404Sblymn 		            lptr = my_lines;
40317c16404Sblymn 	            break;
40417c16404Sblymn 
40517c16404Sblymn #ifdef HAVE_WCHAR
40617c16404Sblymn             case L'r':
40717c16404Sblymn #else
40817c16404Sblymn 	        case 'r':
40917c16404Sblymn #endif /* HAVE_WCHAR */
41017c16404Sblymn 	        case KEY_RIGHT:
41117c16404Sblymn 	            shift += n;
41217c16404Sblymn 	            break;
41317c16404Sblymn 
41417c16404Sblymn #ifdef HAVE_WCHAR
41517c16404Sblymn             case L'l':
41617c16404Sblymn #else
41717c16404Sblymn 	        case 'l':
41817c16404Sblymn #endif /* HAVE_WCHAR */
41917c16404Sblymn 	        case KEY_LEFT:
42017c16404Sblymn 	            shift -= n;
42117c16404Sblymn 	            if (shift < 0) {
42217c16404Sblymn 		            shift = 0;
42317c16404Sblymn 		            beep();
42417c16404Sblymn 	            }
42517c16404Sblymn 	            break;
42617c16404Sblymn 
42717c16404Sblymn #ifdef HAVE_WCHAR
42817c16404Sblymn             case L'q':
42917c16404Sblymn #else
43017c16404Sblymn 	        case 'q':
43117c16404Sblymn #endif /* HAVE_WCHAR */
43217c16404Sblymn 	            done = TRUE;
43317c16404Sblymn 	            break;
43417c16404Sblymn 
43517c16404Sblymn #ifdef KEY_RESIZE
43617c16404Sblymn 	        case KEY_RESIZE:
43717c16404Sblymn                 //refresh();
43817c16404Sblymn 	            break;
43917c16404Sblymn #endif
44017c16404Sblymn #ifdef HAVE_WCHAR
44117c16404Sblymn 	        case L's':
44217c16404Sblymn #else
44317c16404Sblymn             case 's':
44417c16404Sblymn #endif /* HAVE_WCHAR */
44517c16404Sblymn 	            if (got_number) {
44617c16404Sblymn 		            halfdelay(my_delay = n);
44717c16404Sblymn 	            } else {
44817c16404Sblymn 		            nodelay(stdscr, FALSE);
44917c16404Sblymn 		            my_delay = -1;
45017c16404Sblymn 	            }
45117c16404Sblymn 	            break;
45217c16404Sblymn #ifdef HAVE_WCHAR
45317c16404Sblymn             case L' ':
45417c16404Sblymn #else
45517c16404Sblymn 	        case ' ':
45617c16404Sblymn #endif /* HAVE_WCHAR */
45717c16404Sblymn 	            nodelay(stdscr, TRUE);
45817c16404Sblymn 	            my_delay = 0;
45917c16404Sblymn 	            break;
46017c16404Sblymn #ifndef HAVE_WCHAR
46117c16404Sblymn 	        case ERR:
46217c16404Sblymn 	            if (!my_delay)
46317c16404Sblymn 		            napms(50);
46417c16404Sblymn 	            break;
46517c16404Sblymn #endif /* HAVE_WCHAR */
46617c16404Sblymn 	        default:
46717c16404Sblymn 	            beep();
46817c16404Sblymn 	            break;
46917c16404Sblymn 	    }
47017c16404Sblymn 	    if (c >= KEY_MIN || (c > 0 && !isdigit(c))) {
47117c16404Sblymn 	        got_number = FALSE;
47217c16404Sblymn 	        value = 0;
47317c16404Sblymn 	    }
47417c16404Sblymn     }
47517c16404Sblymn 
47617c16404Sblymn     finish(0);			/* we're done */
47717c16404Sblymn }
47817c16404Sblymn 
finish(int sig)47917c16404Sblymn static void finish(int sig)
48017c16404Sblymn {
48117c16404Sblymn     endwin();
48217c16404Sblymn     exit(sig != 0 ?  1 : 0 );
48317c16404Sblymn }
48417c16404Sblymn 
show_all(const char * tag)48517c16404Sblymn static void show_all(const char *tag)
48617c16404Sblymn {
48717c16404Sblymn     int i;
48817c16404Sblymn     char temp[BUFSIZ];
48917c16404Sblymn     CURSES_CH_T *s;
49017c16404Sblymn     time_t this_time;
49117c16404Sblymn 
49217c16404Sblymn     sprintf(temp, "%s (%3dx%3d) col %d ", tag, LINES, COLS, shift);
49317c16404Sblymn     i = strlen(temp);
49417c16404Sblymn     sprintf(temp + i, "view %.*s", (int) (sizeof(temp) - 7 - i), fname);
49517c16404Sblymn     move(0, 0);
49617c16404Sblymn     printw("%.*s", COLS, temp);
49717c16404Sblymn     clrtoeol();
49817c16404Sblymn     this_time = time((time_t *) 0);
49917c16404Sblymn     strcpy(temp, ctime(&this_time));
50017c16404Sblymn     if ((i = strlen(temp)) != 0) {
50117c16404Sblymn 	    temp[--i] = 0;
50217c16404Sblymn 	    if (move(0, COLS - i - 2) != ERR)
50317c16404Sblymn 	        printw("  %s", temp);
50417c16404Sblymn     }
50517c16404Sblymn 
50617c16404Sblymn     scrollok(stdscr, FALSE);	/* prevent screen from moving */
50717c16404Sblymn     for (i = 1; i < LINES; i++) {
50817c16404Sblymn 	    move(i, 0);
50917c16404Sblymn 	    printw("%3ld:", (long) (lptr + i - my_lines));
51017c16404Sblymn 	    clrtoeol();
51117c16404Sblymn 	    if ((s = lptr[i - 1]) != 0) {
512*e124de36Sblymn 		    if (i < num_lines) {
51317c16404Sblymn 			    int len = ch_len(s);
51417c16404Sblymn 			    if (len > shift) {
51517c16404Sblymn #ifdef HAVE_WCHAR
51617c16404Sblymn 				    add_wchstr(s + shift);
51717c16404Sblymn #else
51817c16404Sblymn 				    addchstr(s + shift);
51917c16404Sblymn #endif
52017c16404Sblymn 			    }
52117c16404Sblymn 		    }
52217c16404Sblymn 	    }
523*e124de36Sblymn     }
52417c16404Sblymn     setscrreg(1, LINES - 1);
52517c16404Sblymn     scrollok(stdscr, TRUE);
52617c16404Sblymn     refresh();
52717c16404Sblymn }
528