1*ef363e2dSmrg /* $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*ef363e2dSmrg __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*ef363e2dSmrg clearerror();
98d0e3cec2Sjwise display(0);
99d0e3cec2Sjwise break;
100d0e3cec2Sjwise case CTRL('l'):
101*ef363e2dSmrg 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 }
12687f2ce05Sbad 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