xref: /netbsd/usr.bin/systat/keyboard.c (revision ce6d12cf)
1*ce6d12cfSmrg /*	$NetBSD: keyboard.c,v 1.26 2015/08/23 18:33:15 mrg Exp $	*/
22f3cb7aeSjtc 
312749a2aSjtc /*-
412749a2aSjtc  * Copyright (c) 1980, 1992, 1993
512749a2aSjtc  *	The Regents of the University of California.  All rights reserved.
612749a2aSjtc  *
712749a2aSjtc  * Redistribution and use in source and binary forms, with or without
812749a2aSjtc  * modification, are permitted provided that the following conditions
912749a2aSjtc  * are met:
1012749a2aSjtc  * 1. Redistributions of source code must retain the above copyright
1112749a2aSjtc  *    notice, this list of conditions and the following disclaimer.
1212749a2aSjtc  * 2. Redistributions in binary form must reproduce the above copyright
1312749a2aSjtc  *    notice, this list of conditions and the following disclaimer in the
1412749a2aSjtc  *    documentation and/or other materials provided with the distribution.
1589aaa1bbSagc  * 3. Neither the name of the University nor the names of its contributors
1612749a2aSjtc  *    may be used to endorse or promote products derived from this software
1712749a2aSjtc  *    without specific prior written permission.
1812749a2aSjtc  *
1912749a2aSjtc  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2012749a2aSjtc  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2112749a2aSjtc  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2212749a2aSjtc  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2312749a2aSjtc  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2412749a2aSjtc  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2512749a2aSjtc  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2612749a2aSjtc  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2712749a2aSjtc  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2812749a2aSjtc  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2912749a2aSjtc  * SUCH DAMAGE.
3012749a2aSjtc  */
3112749a2aSjtc 
3259413993Smrg #include <sys/cdefs.h>
3312749a2aSjtc #ifndef lint
342f3cb7aeSjtc #if 0
3512749a2aSjtc static char sccsid[] = "@(#)keyboard.c	8.1 (Berkeley) 6/6/93";
362f3cb7aeSjtc #endif
37*ce6d12cfSmrg __RCSID("$NetBSD: keyboard.c,v 1.26 2015/08/23 18:33:15 mrg Exp $");
3812749a2aSjtc #endif /* not lint */
3912749a2aSjtc 
4047abaab8Smrg #include <sys/types.h>
4147abaab8Smrg 
4212749a2aSjtc #include <ctype.h>
4312749a2aSjtc #include <signal.h>
4412749a2aSjtc #include <termios.h>
4547abaab8Smrg #include <stdlib.h>
46019733f6Sdsl #include <string.h>
475665eef1Schristos #include <signal.h>
4812749a2aSjtc 
4912749a2aSjtc #include "systat.h"
5012749a2aSjtc #include "extern.h"
5112749a2aSjtc 
525665eef1Schristos extern sig_atomic_t needsredraw;
535665eef1Schristos 
549df8f56aSmartin void
keyboard(void)55fc391547Sad keyboard(void)
5612749a2aSjtc {
57019733f6Sdsl 	int ch, rch, col;
5830aaa906Smycroft 	char *line;
59728f40d7Ssommerfeld 	int i, linesz;
60019733f6Sdsl 	static char help[] = "help";
61019733f6Sdsl 	static char quit[] = "quit";
6212749a2aSjtc 
63084c0528Smrg 	ch = 0;	/* XXX gcc */
6447abaab8Smrg 	linesz = COLS - 2;		/* XXX does not get updated on SIGWINCH */
65850fb37fSjwise 	if ((line = malloc(linesz)) == NULL) {
66850fb37fSjwise 		error("malloc failed");
67850fb37fSjwise 		die(0);
6847abaab8Smrg 	}
6947abaab8Smrg 
7012749a2aSjtc 	for (;;) {
7112749a2aSjtc 		col = 0;
7212749a2aSjtc 		move(CMDLINE, 0);
73d0e3cec2Sjwise 
74d0e3cec2Sjwise 		while (col == 0 || (ch != '\r' && ch != '\n')) {
7512749a2aSjtc 			refresh();
765665eef1Schristos 			for (;;) {
7730aaa906Smycroft 				ch = getch();
785665eef1Schristos 				if (!needsredraw)
795665eef1Schristos 					break;
805665eef1Schristos 				redraw();
815665eef1Schristos 			}
82eb8fd502Smycroft 			if (ch == ERR) {
83f702e254Smycroft 				display(SIGALRM);
8412749a2aSjtc 				continue;
8512749a2aSjtc 			}
86eb8fd502Smycroft 			if (ch == KEY_RESIZE) {
875665eef1Schristos 				redraw();
88eb8fd502Smycroft 				continue;
89eb8fd502Smycroft 			}
9030aaa906Smycroft 			ch &= 0177;
91728f40d7Ssommerfeld 			rch = ch;
9212749a2aSjtc 			if (col == 0) {
93d0e3cec2Sjwise 				switch(ch) {
94d0e3cec2Sjwise 				    case '\n':
95d0e3cec2Sjwise 				    case '\r':
96d0e3cec2Sjwise 				    case ' ':
97*ce6d12cfSmrg 					clearerror();
98d0e3cec2Sjwise 					display(0);
99d0e3cec2Sjwise 					break;
100d0e3cec2Sjwise 				    case CTRL('l'):
101*ce6d12cfSmrg 					clearerror();
10212749a2aSjtc 					wrefresh(curscr);
103d0e3cec2Sjwise 					break;
104d0e3cec2Sjwise 				    case CTRL('g'):
10512749a2aSjtc 					status();
106d0e3cec2Sjwise 					break;
107d0e3cec2Sjwise 				    case '?':
108ad285dbfSjwise 				    case 'H':
109d0e3cec2Sjwise 				    case 'h':
110019733f6Sdsl 					command(help);
111b80f4eafSsimonb 					move(CMDLINE, 0);
112d0e3cec2Sjwise 					break;
113ad285dbfSjwise 				    case 'Q':
114a84dcb30Smycroft 				    case 'q':
115019733f6Sdsl 					command(quit);
116ad285dbfSjwise 					break;
117d0e3cec2Sjwise 				    case ':':
11812749a2aSjtc 					move(CMDLINE, 0);
11912749a2aSjtc 					clrtoeol();
120d0e3cec2Sjwise 					addch(':');
121d0e3cec2Sjwise 					col++;
122d0e3cec2Sjwise 					break;
123d0e3cec2Sjwise 				}
124d0e3cec2Sjwise 				continue;
12512749a2aSjtc 			}
1265a70388eSbad 			if (ch == '\b' || ch == '\177' || ch == erasechar()) {
1275af29647Sdsl 				if (col > 0)
12812749a2aSjtc 					col--;
12912749a2aSjtc 				goto doerase;
13012749a2aSjtc 			}
13112749a2aSjtc 			if (ch == CTRL('w') && col > 0) {
132cf09d2b1Sdsl 				while (--col >= 0 &&
133cf09d2b1Sdsl 				    isspace((unsigned char)line[col]))
134cf09d2b1Sdsl 					continue;
13512749a2aSjtc 				col++;
136cf09d2b1Sdsl 				while (--col >= 0 &&
137cf09d2b1Sdsl 				    !isspace((unsigned char)line[col]))
138d0e3cec2Sjwise 					if (col == 0)
13912749a2aSjtc 						break;
14012749a2aSjtc 				col++;
14112749a2aSjtc 				goto doerase;
14212749a2aSjtc 			}
14312749a2aSjtc 			if (ch == killchar() && col > 0) {
14447abaab8Smrg 				col = 1;
14512749a2aSjtc 		doerase:
14612749a2aSjtc 				move(CMDLINE, col);
14712749a2aSjtc 				clrtoeol();
14812749a2aSjtc 				continue;
14912749a2aSjtc 			}
150d0e3cec2Sjwise 			if (isprint(rch) || rch == ' ') {
15147abaab8Smrg 				if (col < linesz) {
152728f40d7Ssommerfeld 					line[col] = rch;
153728f40d7Ssommerfeld 					mvaddch(CMDLINE, col, rch);
15412749a2aSjtc 					col++;
15512749a2aSjtc 				}
15647abaab8Smrg 			}
157d0e3cec2Sjwise 		}
15812749a2aSjtc 		line[col] = '\0';
159728f40d7Ssommerfeld 		/* pass commands as lowercase */
160d0e3cec2Sjwise 		for (i = 1; i < col ; i++)
161cf09d2b1Sdsl 			line[i] = tolower((unsigned char)line[i]);
16212749a2aSjtc 		command(line + 1);
16312749a2aSjtc 	}
16412749a2aSjtc 	/* NOTREACHED */
16512749a2aSjtc }
166