1*51ffecc1SBen Gras /*
2*51ffecc1SBen Gras * view.c -- a silly little viewer program
3*51ffecc1SBen Gras *
4*51ffecc1SBen Gras * written by Eric S. Raymond <esr@snark.thyrsus.com> December 1994
5*51ffecc1SBen Gras * to test the scrolling code in ncurses.
6*51ffecc1SBen Gras *
7*51ffecc1SBen Gras * modified by Thomas Dickey <dickey@clark.net> July 1995 to demonstrate
8*51ffecc1SBen Gras * the use of 'resizeterm()', and May 2000 to illustrate wide-character
9*51ffecc1SBen Gras * handling.
10*51ffecc1SBen Gras *
11*51ffecc1SBen Gras * Takes a filename argument. It's a simple file-viewer with various
12*51ffecc1SBen Gras * scroll-up and scroll-down commands.
13*51ffecc1SBen Gras *
14*51ffecc1SBen Gras * n -- scroll one line forward
15*51ffecc1SBen Gras * p -- scroll one line back
16*51ffecc1SBen Gras *
17*51ffecc1SBen Gras * Either command accepts a numeric prefix interpreted as a repeat count.
18*51ffecc1SBen Gras * Thus, typing `5n' should scroll forward 5 lines in the file.
19*51ffecc1SBen Gras *
20*51ffecc1SBen Gras * The way you can tell this is working OK is that, in the trace file,
21*51ffecc1SBen Gras * there should be one scroll operation plus a small number of line
22*51ffecc1SBen Gras * updates, as opposed to a whole-page update. This means the physical
23*51ffecc1SBen Gras * scroll operation worked, and the refresh() code only had to do a
24*51ffecc1SBen Gras * partial repaint.
25*51ffecc1SBen Gras *
26*51ffecc1SBen Gras * $Id: view.c,v 1.2 2007/05/28 15:01:58 blymn Exp $
27*51ffecc1SBen Gras */
28*51ffecc1SBen Gras
29*51ffecc1SBen Gras #include <stdlib.h>
30*51ffecc1SBen Gras #include <string.h>
31*51ffecc1SBen Gras #include <sys/types.h>
32*51ffecc1SBen Gras #include <signal.h>
33*51ffecc1SBen Gras #ifdef NCURSES
34*51ffecc1SBen Gras #define _XOPEN_SOURCE_EXTENDED
35*51ffecc1SBen Gras #include <ncurses.h>
36*51ffecc1SBen Gras #include <term.h>
37*51ffecc1SBen Gras #else
38*51ffecc1SBen Gras #include <curses.h>
39*51ffecc1SBen Gras #endif /* NCURSES */
40*51ffecc1SBen Gras #include <locale.h>
41*51ffecc1SBen Gras #include <assert.h>
42*51ffecc1SBen Gras #include <ctype.h>
43*51ffecc1SBen Gras #include <termios.h>
44*51ffecc1SBen Gras #include <util.h>
45*51ffecc1SBen Gras #include <unistd.h>
46*51ffecc1SBen Gras #ifdef HAVE_WCHAR
47*51ffecc1SBen Gras #include <wchar.h>
48*51ffecc1SBen Gras #endif /* HAVE_WCHAR */
49*51ffecc1SBen Gras #ifdef DEBUG
50*51ffecc1SBen Gras #include <syslog.h>
51*51ffecc1SBen Gras #endif /* DEBUG */
52*51ffecc1SBen Gras
53*51ffecc1SBen Gras #define UChar(c) ((unsigned char)(c))
54*51ffecc1SBen Gras #define SIZEOF(table) (sizeof(table)/sizeof(table[0]))
55*51ffecc1SBen Gras #define typeMalloc(type,n) (type *) malloc((n) * sizeof(type))
56*51ffecc1SBen Gras
57*51ffecc1SBen Gras #define my_pair 1
58*51ffecc1SBen Gras
59*51ffecc1SBen Gras #undef CURSES_CH_T
60*51ffecc1SBen Gras #ifdef HAVE_WCHAR
61*51ffecc1SBen Gras #define CURSES_CH_T cchar_t
62*51ffecc1SBen Gras #else
63*51ffecc1SBen Gras #define CURSES_CH_T chtype
64*51ffecc1SBen Gras #endif /* HAVE_WCHAR */
65*51ffecc1SBen Gras
66*51ffecc1SBen Gras static void finish(int sig);
67*51ffecc1SBen Gras static void show_all(const char *tag);
68*51ffecc1SBen Gras
69*51ffecc1SBen Gras static int shift = 0;
70*51ffecc1SBen Gras static bool try_color = FALSE;
71*51ffecc1SBen Gras
72*51ffecc1SBen Gras static char *fname;
73*51ffecc1SBen Gras static CURSES_CH_T **my_lines;
74*51ffecc1SBen Gras static CURSES_CH_T **lptr;
75*51ffecc1SBen Gras static unsigned num_lines;
76*51ffecc1SBen Gras
usage(void)77*51ffecc1SBen Gras static void usage(void)
78*51ffecc1SBen Gras {
79*51ffecc1SBen Gras static const char *msg[] = {
80*51ffecc1SBen Gras "Usage: view [options] file"
81*51ffecc1SBen Gras ,""
82*51ffecc1SBen Gras ,"Options:"
83*51ffecc1SBen Gras ," -c use color if terminal supports it"
84*51ffecc1SBen Gras ," -i ignore INT, QUIT, TERM signals"
85*51ffecc1SBen Gras ," -n NUM specify maximum number of lines (default 1000)"
86*51ffecc1SBen Gras #if defined(KEY_RESIZE)
87*51ffecc1SBen Gras ," -r use old-style sigwinch handler rather than KEY_RESIZE"
88*51ffecc1SBen Gras #endif
89*51ffecc1SBen Gras #ifdef TRACE
90*51ffecc1SBen Gras ," -t trace screen updates"
91*51ffecc1SBen Gras ," -T NUM specify trace mask"
92*51ffecc1SBen Gras #endif
93*51ffecc1SBen Gras };
94*51ffecc1SBen Gras size_t n;
95*51ffecc1SBen Gras for (n = 0; n < SIZEOF(msg); n++)
96*51ffecc1SBen Gras fprintf(stderr, "%s\n", msg[n]);
97*51ffecc1SBen Gras exit( 1 );
98*51ffecc1SBen Gras }
99*51ffecc1SBen Gras
ch_len(CURSES_CH_T * src)100*51ffecc1SBen Gras static int ch_len(CURSES_CH_T * src)
101*51ffecc1SBen Gras {
102*51ffecc1SBen Gras int result = 0;
103*51ffecc1SBen Gras
104*51ffecc1SBen Gras #ifdef HAVE_WCHAR
105*51ffecc1SBen Gras while (getcchar(src++, NULL, NULL, NULL, NULL) > 0)
106*51ffecc1SBen Gras result++;
107*51ffecc1SBen Gras #else
108*51ffecc1SBen Gras while (*src++)
109*51ffecc1SBen Gras result++;
110*51ffecc1SBen Gras #endif
111*51ffecc1SBen Gras return result;
112*51ffecc1SBen Gras }
113*51ffecc1SBen Gras
114*51ffecc1SBen Gras /*
115*51ffecc1SBen Gras * Allocate a string into an array of chtype's. If UTF-8 mode is
116*51ffecc1SBen Gras * active, translate the string accordingly.
117*51ffecc1SBen Gras */
ch_dup(char * src)118*51ffecc1SBen Gras static CURSES_CH_T * ch_dup(char *src)
119*51ffecc1SBen Gras {
120*51ffecc1SBen Gras unsigned len = strlen(src);
121*51ffecc1SBen Gras CURSES_CH_T *dst = typeMalloc(CURSES_CH_T, len + 1);
122*51ffecc1SBen Gras unsigned j, k;
123*51ffecc1SBen Gras #ifdef HAVE_WCHAR
124*51ffecc1SBen Gras wchar_t wstr[CCHARW_MAX + 1];
125*51ffecc1SBen Gras wchar_t wch;
126*51ffecc1SBen Gras int l = 0;
127*51ffecc1SBen Gras mbstate_t state;
128*51ffecc1SBen Gras size_t rc;
129*51ffecc1SBen Gras int width;
130*51ffecc1SBen Gras #endif
131*51ffecc1SBen Gras
132*51ffecc1SBen Gras #ifdef HAVE_WCHAR
133*51ffecc1SBen Gras mbrtowc( NULL, NULL, 1, &state );
134*51ffecc1SBen Gras #endif
135*51ffecc1SBen Gras for (j = k = 0; j < len; j++) {
136*51ffecc1SBen Gras #ifdef HAVE_WCHAR
137*51ffecc1SBen Gras rc = mbrtowc(&wch, src + j, len - j, &state);
138*51ffecc1SBen Gras #ifdef DEBUG
139*51ffecc1SBen Gras syslog( LOG_INFO, "[ch_dup]mbrtowc() returns %d", rc );
140*51ffecc1SBen Gras #endif /* DEBUG */
141*51ffecc1SBen Gras if (rc == (size_t) -1 || rc == (size_t) -2)
142*51ffecc1SBen Gras break;
143*51ffecc1SBen Gras j += rc - 1;
144*51ffecc1SBen Gras if ((width = wcwidth(wch)) < 0)
145*51ffecc1SBen Gras break;
146*51ffecc1SBen Gras if ((width > 0 && l > 0) || l == CCHARW_MAX) {
147*51ffecc1SBen Gras wstr[l] = L'\0';
148*51ffecc1SBen Gras l = 0;
149*51ffecc1SBen Gras if (setcchar(dst + k, wstr, 0, 0, NULL) != OK)
150*51ffecc1SBen Gras break;
151*51ffecc1SBen Gras ++k;
152*51ffecc1SBen Gras }
153*51ffecc1SBen Gras if (width == 0 && l == 0)
154*51ffecc1SBen Gras wstr[l++] = L' ';
155*51ffecc1SBen Gras wstr[l++] = wch;
156*51ffecc1SBen Gras #ifdef DEBUG
157*51ffecc1SBen Gras syslog( LOG_INFO, "[ch_dup]wch=%x", wch );
158*51ffecc1SBen Gras #endif /* DEBUG */
159*51ffecc1SBen Gras #else
160*51ffecc1SBen Gras dst[k++] = src[j];
161*51ffecc1SBen Gras #endif
162*51ffecc1SBen Gras }
163*51ffecc1SBen Gras #ifdef HAVE_WCHAR
164*51ffecc1SBen Gras if (l > 0) {
165*51ffecc1SBen Gras wstr[l] = L'\0';
166*51ffecc1SBen Gras if (setcchar(dst + k, wstr, 0, 0, NULL) == OK)
167*51ffecc1SBen Gras ++k;
168*51ffecc1SBen Gras }
169*51ffecc1SBen Gras setcchar(dst + k, L"", 0, 0, NULL);
170*51ffecc1SBen Gras #else
171*51ffecc1SBen Gras dst[k] = 0;
172*51ffecc1SBen Gras #endif
173*51ffecc1SBen Gras return dst;
174*51ffecc1SBen Gras }
175*51ffecc1SBen Gras
main(int argc,char * argv[])176*51ffecc1SBen Gras int main(int argc, char *argv[])
177*51ffecc1SBen Gras {
178*51ffecc1SBen Gras int MAXLINES = 1000;
179*51ffecc1SBen Gras FILE *fp;
180*51ffecc1SBen Gras char buf[BUFSIZ];
181*51ffecc1SBen Gras int i;
182*51ffecc1SBen Gras int my_delay = 0;
183*51ffecc1SBen Gras CURSES_CH_T **olptr;
184*51ffecc1SBen Gras int length = 0;
185*51ffecc1SBen Gras int value = 0;
186*51ffecc1SBen Gras bool done = FALSE;
187*51ffecc1SBen Gras bool got_number = FALSE;
188*51ffecc1SBen Gras const char *my_label = "Input";
189*51ffecc1SBen Gras #ifdef HAVE_WCHAR
190*51ffecc1SBen Gras cchar_t icc;
191*51ffecc1SBen Gras #endif /* HAVE_WCHAR */
192*51ffecc1SBen Gras
193*51ffecc1SBen Gras setlocale(LC_ALL, "");
194*51ffecc1SBen Gras
195*51ffecc1SBen Gras (void) signal(SIGINT, finish); /* arrange interrupts to terminate */
196*51ffecc1SBen Gras
197*51ffecc1SBen Gras while ((i = getopt(argc, argv, "cin:rtT:")) != EOF) {
198*51ffecc1SBen Gras switch (i) {
199*51ffecc1SBen Gras case 'c':
200*51ffecc1SBen Gras try_color = TRUE;
201*51ffecc1SBen Gras break;
202*51ffecc1SBen Gras case 'i':
203*51ffecc1SBen Gras signal(SIGINT, SIG_IGN);
204*51ffecc1SBen Gras signal(SIGQUIT, SIG_IGN);
205*51ffecc1SBen Gras signal(SIGTERM, SIG_IGN);
206*51ffecc1SBen Gras break;
207*51ffecc1SBen Gras case 'n':
208*51ffecc1SBen Gras if ((MAXLINES = atoi(optarg)) < 1)
209*51ffecc1SBen Gras usage();
210*51ffecc1SBen Gras break;
211*51ffecc1SBen Gras #ifdef TRACE
212*51ffecc1SBen Gras case 'T':
213*51ffecc1SBen Gras trace(atoi(optarg));
214*51ffecc1SBen Gras break;
215*51ffecc1SBen Gras case 't':
216*51ffecc1SBen Gras trace(TRACE_CALLS);
217*51ffecc1SBen Gras break;
218*51ffecc1SBen Gras #endif
219*51ffecc1SBen Gras default:
220*51ffecc1SBen Gras usage();
221*51ffecc1SBen Gras }
222*51ffecc1SBen Gras }
223*51ffecc1SBen Gras if (optind + 1 != argc)
224*51ffecc1SBen Gras usage();
225*51ffecc1SBen Gras
226*51ffecc1SBen Gras if ((my_lines = typeMalloc(CURSES_CH_T *, MAXLINES + 2)) == 0)
227*51ffecc1SBen Gras usage();
228*51ffecc1SBen Gras
229*51ffecc1SBen Gras fname = argv[optind];
230*51ffecc1SBen Gras if ((fp = fopen(fname, "r")) == 0) {
231*51ffecc1SBen Gras perror(fname);
232*51ffecc1SBen Gras exit( 1 );
233*51ffecc1SBen Gras }
234*51ffecc1SBen Gras
235*51ffecc1SBen Gras /* slurp the file */
236*51ffecc1SBen Gras num_lines = 0;
237*51ffecc1SBen Gras for (lptr = &my_lines[0]; (lptr - my_lines) < MAXLINES; lptr++) {
238*51ffecc1SBen Gras char temp[BUFSIZ], *s, *d;
239*51ffecc1SBen Gras int col;
240*51ffecc1SBen Gras
241*51ffecc1SBen Gras if (fgets(buf, sizeof(buf), fp) == 0)
242*51ffecc1SBen Gras break;
243*51ffecc1SBen Gras
244*51ffecc1SBen Gras /* convert tabs so that shift will work properly */
245*51ffecc1SBen Gras for (s = buf, d = temp, col = 0; (*d = *s) != '\0'; s++) {
246*51ffecc1SBen Gras if (*d == '\n') {
247*51ffecc1SBen Gras *d = '\0';
248*51ffecc1SBen Gras break;
249*51ffecc1SBen Gras } else if (*d == '\t') {
250*51ffecc1SBen Gras col = (col | 7) + 1;
251*51ffecc1SBen Gras while ((d - temp) != col)
252*51ffecc1SBen Gras *d++ = ' ';
253*51ffecc1SBen Gras } else
254*51ffecc1SBen Gras #ifdef HAVE_WCHAR
255*51ffecc1SBen Gras col++, d++;
256*51ffecc1SBen Gras #else
257*51ffecc1SBen Gras if (isprint(UChar(*d))) {
258*51ffecc1SBen Gras col++;
259*51ffecc1SBen Gras d++;
260*51ffecc1SBen Gras } else {
261*51ffecc1SBen Gras sprintf(d, "\\%03o", UChar(*s));
262*51ffecc1SBen Gras d += strlen(d);
263*51ffecc1SBen Gras col = (d - temp);
264*51ffecc1SBen Gras }
265*51ffecc1SBen Gras #endif
266*51ffecc1SBen Gras }
267*51ffecc1SBen Gras *lptr = ch_dup(temp);
268*51ffecc1SBen Gras num_lines++;
269*51ffecc1SBen Gras }
270*51ffecc1SBen Gras (void) fclose(fp);
271*51ffecc1SBen Gras length = lptr - my_lines;
272*51ffecc1SBen Gras
273*51ffecc1SBen Gras (void) initscr(); /* initialize the curses library */
274*51ffecc1SBen Gras keypad(stdscr, TRUE); /* enable keyboard mapping */
275*51ffecc1SBen Gras (void) nonl(); /* tell curses not to do NL->CR/NL on output */
276*51ffecc1SBen Gras (void) cbreak(); /* take input chars one at a time, no wait for \n */
277*51ffecc1SBen Gras (void) noecho(); /* don't echo input */
278*51ffecc1SBen Gras nodelay(stdscr, TRUE);
279*51ffecc1SBen Gras idlok(stdscr, TRUE); /* allow use of insert/delete line */
280*51ffecc1SBen Gras
281*51ffecc1SBen Gras if (try_color) {
282*51ffecc1SBen Gras if (has_colors()) {
283*51ffecc1SBen Gras start_color();
284*51ffecc1SBen Gras init_pair(my_pair, COLOR_WHITE, COLOR_BLUE);
285*51ffecc1SBen Gras bkgd(COLOR_PAIR(my_pair));
286*51ffecc1SBen Gras } else {
287*51ffecc1SBen Gras try_color = FALSE;
288*51ffecc1SBen Gras }
289*51ffecc1SBen Gras }
290*51ffecc1SBen Gras
291*51ffecc1SBen Gras lptr = my_lines;
292*51ffecc1SBen Gras while (!done) {
293*51ffecc1SBen Gras int n;
294*51ffecc1SBen Gras #ifdef HAVE_WCHAR
295*51ffecc1SBen Gras wint_t c = 0;
296*51ffecc1SBen Gras int ret;
297*51ffecc1SBen Gras #else
298*51ffecc1SBen Gras int c = 0;
299*51ffecc1SBen Gras #endif /* HAVE_WCHAR */
300*51ffecc1SBen Gras
301*51ffecc1SBen Gras if (!got_number)
302*51ffecc1SBen Gras show_all(my_label);
303*51ffecc1SBen Gras
304*51ffecc1SBen Gras n = 0;
305*51ffecc1SBen Gras for (;;) {
306*51ffecc1SBen Gras c = 0;
307*51ffecc1SBen Gras #ifdef HAVE_WCHAR
308*51ffecc1SBen Gras ret = get_wch( &c );
309*51ffecc1SBen Gras if ( ret == ERR ) {
310*51ffecc1SBen Gras if (!my_delay)
311*51ffecc1SBen Gras napms(50);
312*51ffecc1SBen Gras continue;
313*51ffecc1SBen Gras }
314*51ffecc1SBen Gras #ifdef DEBUG
315*51ffecc1SBen Gras else if ( ret == KEY_CODE_YES )
316*51ffecc1SBen Gras syslog( LOG_INFO, "[main]Func key(%x)", c );
317*51ffecc1SBen Gras else
318*51ffecc1SBen Gras syslog( LOG_INFO, "[main]c=%x", c );
319*51ffecc1SBen Gras #endif /* DEBUG */
320*51ffecc1SBen Gras #else
321*51ffecc1SBen Gras c = getch();
322*51ffecc1SBen Gras #ifdef DEBUG
323*51ffecc1SBen Gras syslog( LOG_INFO, "[main]c='%c'", c );
324*51ffecc1SBen Gras #endif /* DEBUG */
325*51ffecc1SBen Gras #endif /* HAVE_WCHAR */
326*51ffecc1SBen Gras if ((c < 127) && isdigit(c)) {
327*51ffecc1SBen Gras if (!got_number) {
328*51ffecc1SBen Gras mvprintw(0, 0, "Count: ");
329*51ffecc1SBen Gras clrtoeol();
330*51ffecc1SBen Gras }
331*51ffecc1SBen Gras addch(c);
332*51ffecc1SBen Gras value = 10 * value + (c - '0');
333*51ffecc1SBen Gras got_number = TRUE;
334*51ffecc1SBen Gras } else
335*51ffecc1SBen Gras break;
336*51ffecc1SBen Gras }
337*51ffecc1SBen Gras if (got_number && value) {
338*51ffecc1SBen Gras n = value;
339*51ffecc1SBen Gras } else {
340*51ffecc1SBen Gras n = 1;
341*51ffecc1SBen Gras }
342*51ffecc1SBen Gras
343*51ffecc1SBen Gras #ifdef HAVE_WCHAR
344*51ffecc1SBen Gras if (ret != ERR)
345*51ffecc1SBen Gras my_label = key_name( c );
346*51ffecc1SBen Gras else
347*51ffecc1SBen Gras if (!my_delay)
348*51ffecc1SBen Gras napms(50);
349*51ffecc1SBen Gras #else
350*51ffecc1SBen Gras if (c != ERR)
351*51ffecc1SBen Gras my_label = keyname(c);
352*51ffecc1SBen Gras #endif /* HAVE_WCHAR */
353*51ffecc1SBen Gras switch (c) {
354*51ffecc1SBen Gras case KEY_DOWN:
355*51ffecc1SBen Gras #ifdef HAVE_WCHAR
356*51ffecc1SBen Gras case L'n':
357*51ffecc1SBen Gras #else
358*51ffecc1SBen Gras case 'n':
359*51ffecc1SBen Gras #endif /* HAVE_WCHAR */
360*51ffecc1SBen Gras olptr = lptr;
361*51ffecc1SBen Gras for (i = 0; i < n; i++)
362*51ffecc1SBen Gras if ((lptr - my_lines) < (length - LINES + 1))
363*51ffecc1SBen Gras lptr++;
364*51ffecc1SBen Gras else
365*51ffecc1SBen Gras break;
366*51ffecc1SBen Gras wscrl(stdscr, lptr - olptr);
367*51ffecc1SBen Gras break;
368*51ffecc1SBen Gras
369*51ffecc1SBen Gras case KEY_UP:
370*51ffecc1SBen Gras #ifdef HAVE_WCHAR
371*51ffecc1SBen Gras case L'p':
372*51ffecc1SBen Gras #else
373*51ffecc1SBen Gras case 'p':
374*51ffecc1SBen Gras #endif /* HAVE_WCHAR */
375*51ffecc1SBen Gras olptr = lptr;
376*51ffecc1SBen Gras for (i = 0; i < n; i++)
377*51ffecc1SBen Gras if (lptr > my_lines)
378*51ffecc1SBen Gras lptr--;
379*51ffecc1SBen Gras else
380*51ffecc1SBen Gras break;
381*51ffecc1SBen Gras wscrl(stdscr, lptr - olptr);
382*51ffecc1SBen Gras break;
383*51ffecc1SBen Gras
384*51ffecc1SBen Gras #ifdef HAVE_WCHAR
385*51ffecc1SBen Gras case L'h':
386*51ffecc1SBen Gras #else
387*51ffecc1SBen Gras case 'h':
388*51ffecc1SBen Gras #endif /* HAVE_WCHAR */
389*51ffecc1SBen Gras case KEY_HOME:
390*51ffecc1SBen Gras lptr = my_lines;
391*51ffecc1SBen Gras break;
392*51ffecc1SBen Gras
393*51ffecc1SBen Gras #ifdef HAVE_WCHAR
394*51ffecc1SBen Gras case L'e':
395*51ffecc1SBen Gras #else
396*51ffecc1SBen Gras case 'e':
397*51ffecc1SBen Gras #endif /* HAVE_WCHAR */
398*51ffecc1SBen Gras case KEY_END:
399*51ffecc1SBen Gras if (length > LINES)
400*51ffecc1SBen Gras lptr = my_lines + length - LINES + 1;
401*51ffecc1SBen Gras else
402*51ffecc1SBen Gras lptr = my_lines;
403*51ffecc1SBen Gras break;
404*51ffecc1SBen Gras
405*51ffecc1SBen Gras #ifdef HAVE_WCHAR
406*51ffecc1SBen Gras case L'r':
407*51ffecc1SBen Gras #else
408*51ffecc1SBen Gras case 'r':
409*51ffecc1SBen Gras #endif /* HAVE_WCHAR */
410*51ffecc1SBen Gras case KEY_RIGHT:
411*51ffecc1SBen Gras shift += n;
412*51ffecc1SBen Gras break;
413*51ffecc1SBen Gras
414*51ffecc1SBen Gras #ifdef HAVE_WCHAR
415*51ffecc1SBen Gras case L'l':
416*51ffecc1SBen Gras #else
417*51ffecc1SBen Gras case 'l':
418*51ffecc1SBen Gras #endif /* HAVE_WCHAR */
419*51ffecc1SBen Gras case KEY_LEFT:
420*51ffecc1SBen Gras shift -= n;
421*51ffecc1SBen Gras if (shift < 0) {
422*51ffecc1SBen Gras shift = 0;
423*51ffecc1SBen Gras beep();
424*51ffecc1SBen Gras }
425*51ffecc1SBen Gras break;
426*51ffecc1SBen Gras
427*51ffecc1SBen Gras #ifdef HAVE_WCHAR
428*51ffecc1SBen Gras case L'q':
429*51ffecc1SBen Gras #else
430*51ffecc1SBen Gras case 'q':
431*51ffecc1SBen Gras #endif /* HAVE_WCHAR */
432*51ffecc1SBen Gras done = TRUE;
433*51ffecc1SBen Gras break;
434*51ffecc1SBen Gras
435*51ffecc1SBen Gras #ifdef KEY_RESIZE
436*51ffecc1SBen Gras case KEY_RESIZE:
437*51ffecc1SBen Gras //refresh();
438*51ffecc1SBen Gras break;
439*51ffecc1SBen Gras #endif
440*51ffecc1SBen Gras #ifdef HAVE_WCHAR
441*51ffecc1SBen Gras case L's':
442*51ffecc1SBen Gras #else
443*51ffecc1SBen Gras case 's':
444*51ffecc1SBen Gras #endif /* HAVE_WCHAR */
445*51ffecc1SBen Gras if (got_number) {
446*51ffecc1SBen Gras halfdelay(my_delay = n);
447*51ffecc1SBen Gras } else {
448*51ffecc1SBen Gras nodelay(stdscr, FALSE);
449*51ffecc1SBen Gras my_delay = -1;
450*51ffecc1SBen Gras }
451*51ffecc1SBen Gras break;
452*51ffecc1SBen Gras #ifdef HAVE_WCHAR
453*51ffecc1SBen Gras case L' ':
454*51ffecc1SBen Gras #else
455*51ffecc1SBen Gras case ' ':
456*51ffecc1SBen Gras #endif /* HAVE_WCHAR */
457*51ffecc1SBen Gras nodelay(stdscr, TRUE);
458*51ffecc1SBen Gras my_delay = 0;
459*51ffecc1SBen Gras break;
460*51ffecc1SBen Gras #ifndef HAVE_WCHAR
461*51ffecc1SBen Gras case ERR:
462*51ffecc1SBen Gras if (!my_delay)
463*51ffecc1SBen Gras napms(50);
464*51ffecc1SBen Gras break;
465*51ffecc1SBen Gras #endif /* HAVE_WCHAR */
466*51ffecc1SBen Gras default:
467*51ffecc1SBen Gras beep();
468*51ffecc1SBen Gras break;
469*51ffecc1SBen Gras }
470*51ffecc1SBen Gras if (c >= KEY_MIN || (c > 0 && !isdigit(c))) {
471*51ffecc1SBen Gras got_number = FALSE;
472*51ffecc1SBen Gras value = 0;
473*51ffecc1SBen Gras }
474*51ffecc1SBen Gras }
475*51ffecc1SBen Gras
476*51ffecc1SBen Gras finish(0); /* we're done */
477*51ffecc1SBen Gras }
478*51ffecc1SBen Gras
finish(int sig)479*51ffecc1SBen Gras static void finish(int sig)
480*51ffecc1SBen Gras {
481*51ffecc1SBen Gras endwin();
482*51ffecc1SBen Gras exit(sig != 0 ? 1 : 0 );
483*51ffecc1SBen Gras }
484*51ffecc1SBen Gras
show_all(const char * tag)485*51ffecc1SBen Gras static void show_all(const char *tag)
486*51ffecc1SBen Gras {
487*51ffecc1SBen Gras int i;
488*51ffecc1SBen Gras char temp[BUFSIZ];
489*51ffecc1SBen Gras CURSES_CH_T *s;
490*51ffecc1SBen Gras time_t this_time;
491*51ffecc1SBen Gras
492*51ffecc1SBen Gras sprintf(temp, "%s (%3dx%3d) col %d ", tag, LINES, COLS, shift);
493*51ffecc1SBen Gras i = strlen(temp);
494*51ffecc1SBen Gras sprintf(temp + i, "view %.*s", (int) (sizeof(temp) - 7 - i), fname);
495*51ffecc1SBen Gras move(0, 0);
496*51ffecc1SBen Gras printw("%.*s", COLS, temp);
497*51ffecc1SBen Gras clrtoeol();
498*51ffecc1SBen Gras this_time = time((time_t *) 0);
499*51ffecc1SBen Gras strcpy(temp, ctime(&this_time));
500*51ffecc1SBen Gras if ((i = strlen(temp)) != 0) {
501*51ffecc1SBen Gras temp[--i] = 0;
502*51ffecc1SBen Gras if (move(0, COLS - i - 2) != ERR)
503*51ffecc1SBen Gras printw(" %s", temp);
504*51ffecc1SBen Gras }
505*51ffecc1SBen Gras
506*51ffecc1SBen Gras scrollok(stdscr, FALSE); /* prevent screen from moving */
507*51ffecc1SBen Gras for (i = 1; i < LINES; i++) {
508*51ffecc1SBen Gras move(i, 0);
509*51ffecc1SBen Gras printw("%3ld:", (long) (lptr + i - my_lines));
510*51ffecc1SBen Gras clrtoeol();
511*51ffecc1SBen Gras if ((s = lptr[i - 1]) != 0) {
512*51ffecc1SBen Gras if (i < num_lines) {
513*51ffecc1SBen Gras int len = ch_len(s);
514*51ffecc1SBen Gras if (len > shift) {
515*51ffecc1SBen Gras #ifdef HAVE_WCHAR
516*51ffecc1SBen Gras add_wchstr(s + shift);
517*51ffecc1SBen Gras #else
518*51ffecc1SBen Gras addchstr(s + shift);
519*51ffecc1SBen Gras #endif
520*51ffecc1SBen Gras }
521*51ffecc1SBen Gras }
522*51ffecc1SBen Gras }
523*51ffecc1SBen Gras }
524*51ffecc1SBen Gras setscrreg(1, LINES - 1);
525*51ffecc1SBen Gras scrollok(stdscr, TRUE);
526*51ffecc1SBen Gras refresh();
527*51ffecc1SBen Gras }
528