11590Srgrimes/*- 21590Srgrimes * Copyright (c) 1980, 1992, 1993 31590Srgrimes * The Regents of the University of California. All rights reserved. 41590Srgrimes * 51590Srgrimes * Redistribution and use in source and binary forms, with or without 61590Srgrimes * modification, are permitted provided that the following conditions 71590Srgrimes * are met: 81590Srgrimes * 1. Redistributions of source code must retain the above copyright 91590Srgrimes * notice, this list of conditions and the following disclaimer. 101590Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 111590Srgrimes * notice, this list of conditions and the following disclaimer in the 121590Srgrimes * documentation and/or other materials provided with the distribution. 131590Srgrimes * 4. Neither the name of the University nor the names of its contributors 141590Srgrimes * may be used to endorse or promote products derived from this software 151590Srgrimes * without specific prior written permission. 161590Srgrimes * 171590Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 181590Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 191590Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 201590Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 211590Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 221590Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 231590Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 241590Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 251590Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 261590Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 271590Srgrimes * SUCH DAMAGE. 281590Srgrimes */ 291590Srgrimes 3087715Smarkm#include <sys/cdefs.h> 311590Srgrimes 3287715Smarkm__FBSDID("$FreeBSD$"); 3387715Smarkm 3487715Smarkm#ifdef lint 3587715Smarkmstatic const char sccsid[] = "@(#)keyboard.c 8.1 (Berkeley) 6/6/93"; 3687715Smarkm#endif 3787715Smarkm 38240605Smelifaro#include <sys/select.h> 39240605Smelifaro#include <sys/time.h> 40240605Smelifaro 41197956Sjh#include <errno.h> 421590Srgrimes#include <ctype.h> 43197956Sjh#include <stdlib.h> 441590Srgrimes#include <termios.h> 45240605Smelifaro#include <unistd.h> 461590Srgrimes 471590Srgrimes#include "systat.h" 481590Srgrimes#include "extern.h" 491590Srgrimes 50240605Smelifarostatic char line[80]; 51240605Smelifarostatic int keyboard_dispatch(int ch); 52240605Smelifaro 531590Srgrimesint 54175387Sdelphijkeyboard(void) 551590Srgrimes{ 56240605Smelifaro int ch, n; 57240605Smelifaro struct timeval last, intvl, now, tm; 58240605Smelifaro fd_set rfds; 591590Srgrimes 60240605Smelifaro /* Set initial timings */ 61240605Smelifaro gettimeofday(&last, NULL); 62240605Smelifaro intvl.tv_sec = delay / 1000000; 63240605Smelifaro intvl.tv_usec = delay % 1000000; 64226396Sed for (;;) { 65226396Sed col = 0; 66226396Sed move(CMDLINE, 0); 67240605Smelifaro for (;;) { 68240605Smelifaro /* Determine interval to sleep */ 69240605Smelifaro (void)gettimeofday(&now, NULL); 70240605Smelifaro tm.tv_sec = last.tv_sec + intvl.tv_sec - now.tv_sec; 71240605Smelifaro tm.tv_usec = last.tv_usec + intvl.tv_usec - now.tv_usec; 72240605Smelifaro while (tm.tv_usec < 0) { 73240605Smelifaro tm.tv_usec += 1000000; 74240605Smelifaro tm.tv_sec--; 75226396Sed } 76240605Smelifaro while (tm.tv_usec >= 1000000) { 77240605Smelifaro tm.tv_usec -= 1000000; 78240605Smelifaro tm.tv_sec++; 79226396Sed } 80240605Smelifaro if (tm.tv_sec < 0) { 81240605Smelifaro /* We have to update screen immediately */ 82240605Smelifaro display(); 83240605Smelifaro gettimeofday(&last, NULL); 84226396Sed continue; 85226396Sed } 86240605Smelifaro 87240605Smelifaro /* Prepare select */ 88240605Smelifaro FD_ZERO(&rfds); 89240605Smelifaro FD_SET(STDIN_FILENO, &rfds); 90240605Smelifaro n = select(STDIN_FILENO + 1, &rfds, NULL, NULL, &tm); 91240605Smelifaro 92240605Smelifaro if (n > 0) { 93240605Smelifaro /* Read event on stdin */ 94240605Smelifaro ch = getch(); 95240605Smelifaro 96240605Smelifaro if (keyboard_dispatch(ch) == 0) { 97240605Smelifaro refresh(); 98240605Smelifaro continue; 99240605Smelifaro } 100240605Smelifaro 101240605Smelifaro line[col] = '\0'; 102240605Smelifaro command(line + 1); 103240605Smelifaro /* Refresh delay */ 104240605Smelifaro intvl.tv_sec = delay / 1000000; 105240605Smelifaro intvl.tv_usec = delay % 1000000; 106240605Smelifaro refresh(); 107240605Smelifaro break; 108226396Sed } 109240605Smelifaro 110240605Smelifaro if (n < 0 && errno != EINTR) 111240605Smelifaro exit(1); 112240605Smelifaro 113240605Smelifaro /* Timeout or signal. Call display another time */ 114240605Smelifaro display(); 115240605Smelifaro gettimeofday(&last, NULL); 116240605Smelifaro } 117226396Sed } 1181590Srgrimes} 119240605Smelifaro 120240605Smelifarostatic int 121240605Smelifarokeyboard_dispatch(int ch) 122240605Smelifaro{ 123240605Smelifaro 124240605Smelifaro if (ch == ERR) { 125240605Smelifaro if (errno == EINTR) 126240605Smelifaro return 0; 127240605Smelifaro exit(1); 128240605Smelifaro } 129240605Smelifaro if (ch >= 'A' && ch <= 'Z') 130240605Smelifaro ch += 'a' - 'A'; 131240605Smelifaro if (col == 0) { 132240605Smelifaro if (ch == CTRL('l')) { 133240605Smelifaro wrefresh(curscr); 134240605Smelifaro return 0; 135240605Smelifaro } 136240605Smelifaro if (ch == CTRL('g')) { 137240605Smelifaro status(); 138240605Smelifaro return 0; 139240605Smelifaro } 140240605Smelifaro if (ch != ':') 141240605Smelifaro return 0; 142240605Smelifaro move(CMDLINE, 0); 143240605Smelifaro clrtoeol(); 144240605Smelifaro } 145240605Smelifaro if (ch == erasechar() && col > 0) { 146240605Smelifaro if (col == 1 && line[0] == ':') 147240605Smelifaro return 0; 148240605Smelifaro col--; 149240605Smelifaro goto doerase; 150240605Smelifaro } 151240605Smelifaro if (ch == CTRL('w') && col > 0) { 152240605Smelifaro while (--col >= 0 && isspace(line[col])) 153240605Smelifaro ; 154240605Smelifaro col++; 155240605Smelifaro while (--col >= 0 && !isspace(line[col])) 156240605Smelifaro if (col == 0 && line[0] == ':') 157240605Smelifaro return 1; 158240605Smelifaro col++; 159240605Smelifaro goto doerase; 160240605Smelifaro } 161240605Smelifaro if (ch == killchar() && col > 0) { 162240605Smelifaro col = 0; 163240605Smelifaro if (line[0] == ':') 164240605Smelifaro col++; 165240605Smelifarodoerase: 166240605Smelifaro move(CMDLINE, col); 167240605Smelifaro clrtoeol(); 168240605Smelifaro return 0; 169240605Smelifaro } 170240605Smelifaro if (isprint(ch) || ch == ' ') { 171240605Smelifaro line[col] = ch; 172240605Smelifaro mvaddch(CMDLINE, col, ch); 173240605Smelifaro col++; 174240605Smelifaro } 175240605Smelifaro 176240605Smelifaro if (col == 0 || (ch != '\r' && ch != '\n')) 177240605Smelifaro return 0; 178240605Smelifaro 179240605Smelifaro return 1; 180240605Smelifaro} 181