1238104Sdes/* $NetBSD: keyboard.c,v 1.23 2006/05/10 21:53:48 mrg Exp $ */ 2238104Sdes 3238104Sdes/*- 4238104Sdes * Copyright (c) 1980, 1992, 1993 5238104Sdes * The Regents of the University of California. All rights reserved. 6238104Sdes * 7238104Sdes * Redistribution and use in source and binary forms, with or without 8238104Sdes * modification, are permitted provided that the following conditions 9238104Sdes * are met: 10238104Sdes * 1. Redistributions of source code must retain the above copyright 11238104Sdes * notice, this list of conditions and the following disclaimer. 12238104Sdes * 2. Redistributions in binary form must reproduce the above copyright 13238104Sdes * notice, this list of conditions and the following disclaimer in the 14238104Sdes * documentation and/or other materials provided with the distribution. 15238104Sdes * 3. Neither the name of the University nor the names of its contributors 16238104Sdes * may be used to endorse or promote products derived from this software 17238104Sdes * without specific prior written permission. 18238104Sdes * 19238104Sdes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 20238104Sdes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21238104Sdes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22238104Sdes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 23238104Sdes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24238104Sdes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25238104Sdes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26238104Sdes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27238104Sdes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28238104Sdes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29238104Sdes * SUCH DAMAGE. 30238104Sdes */ 31238104Sdes 32238104Sdes#include <sys/cdefs.h> 33238104Sdes#ifndef lint 34238104Sdes#if 0 35238104Sdesstatic char sccsid[] = "@(#)keyboard.c 8.1 (Berkeley) 6/6/93"; 36238104Sdes#endif 37238104Sdes__RCSID("$NetBSD: keyboard.c,v 1.23 2006/05/10 21:53:48 mrg Exp $"); 38238104Sdes#endif /* not lint */ 39238104Sdes 40238104Sdes#include <sys/types.h> 41238104Sdes 42238104Sdes#include <ctype.h> 43238104Sdes#include <signal.h> 44238104Sdes#include <termios.h> 45238104Sdes#include <stdlib.h> 46238104Sdes#include <string.h> 47238104Sdes#include <signal.h> 48238104Sdes 49238104Sdes#include "systat.h" 50238104Sdes#include "extern.h" 51238104Sdes 52238104Sdesextern sig_atomic_t needsredraw; 53238104Sdes 54238104Sdesvoid 55238104Sdeskeyboard(void) 56238104Sdes{ 57238104Sdes int ch, rch, col; 58238104Sdes char *line; 59238104Sdes int i, linesz; 60238104Sdes static char help[] = "help"; 61238104Sdes static char quit[] = "quit"; 62238104Sdes 63238104Sdes ch = 0; /* XXX gcc */ 64238104Sdes linesz = COLS - 2; /* XXX does not get updated on SIGWINCH */ 65238104Sdes if ((line = malloc(linesz)) == NULL) { 66238104Sdes error("malloc failed"); 67238104Sdes die(0); 68238104Sdes } 69238104Sdes 70238104Sdes for (;;) { 71238104Sdes col = 0; 72238104Sdes move(CMDLINE, 0); 73238104Sdes 74238104Sdes while (col == 0 || (ch != '\r' && ch != '\n')) { 75238104Sdes refresh(); 76238104Sdes for (;;) { 77238104Sdes ch = getch(); 78238104Sdes if (!needsredraw) 79238104Sdes break; 80238104Sdes redraw(); 81238104Sdes } 82238104Sdes if (ch == ERR) { 83238104Sdes display(SIGALRM); 84238104Sdes continue; 85238104Sdes } 86238104Sdes if (ch == KEY_RESIZE) { 87238104Sdes redraw(); 88238104Sdes continue; 89238104Sdes } 90238104Sdes ch &= 0177; 91238104Sdes rch = ch; 92238104Sdes if (col == 0) { 93238104Sdes switch(ch) { 94238104Sdes case '\n': 95238104Sdes case '\r': 96238104Sdes case ' ': 97238104Sdes display(0); 98238104Sdes break; 99238104Sdes case CTRL('l'): 100238104Sdes wrefresh(curscr); 101238104Sdes break; 102238104Sdes case CTRL('g'): 103238104Sdes status(); 104238104Sdes break; 105238104Sdes case '?': 106238104Sdes case 'H': 107238104Sdes case 'h': 108238104Sdes command(help); 109238104Sdes move(CMDLINE, 0); 110238104Sdes break; 111238104Sdes case 'Q': 112238104Sdes case 'q': 113238104Sdes command(quit); 114238104Sdes break; 115238104Sdes case ':': 116238104Sdes move(CMDLINE, 0); 117238104Sdes clrtoeol(); 118238104Sdes addch(':'); 119238104Sdes col++; 120238104Sdes break; 121238104Sdes } 122238104Sdes continue; 123238104Sdes } 124238104Sdes if (ch == '\b' || ch == '\?' || ch == erasechar()) { 125238104Sdes if (col > 0) 126238104Sdes col--; 127238104Sdes goto doerase; 128238104Sdes } 129238104Sdes if (ch == CTRL('w') && col > 0) { 130238104Sdes while (--col >= 0 && 131238104Sdes isspace((unsigned char)line[col])) 132238104Sdes continue; 133238104Sdes col++; 134238104Sdes while (--col >= 0 && 135238104Sdes !isspace((unsigned char)line[col])) 136238104Sdes if (col == 0) 137238104Sdes break; 138238104Sdes col++; 139238104Sdes goto doerase; 140238104Sdes } 141238104Sdes if (ch == killchar() && col > 0) { 142238104Sdes col = 1; 143238104Sdes doerase: 144238104Sdes move(CMDLINE, col); 145238104Sdes clrtoeol(); 146238104Sdes continue; 147238104Sdes } 148238104Sdes if (isprint(rch) || rch == ' ') { 149238104Sdes if (col < linesz) { 150238104Sdes line[col] = rch; 151238104Sdes mvaddch(CMDLINE, col, rch); 152238104Sdes col++; 153238104Sdes } 154238104Sdes } 155238104Sdes } 156238104Sdes line[col] = '\0'; 157238104Sdes /* pass commands as lowercase */ 158238104Sdes for (i = 1; i < col ; i++) 159238104Sdes line[i] = tolower((unsigned char)line[i]); 160238104Sdes command(line + 1); 161238104Sdes } 162238104Sdes /* NOTREACHED */ 163238104Sdes} 164238104Sdes