]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - usr.bin/systat/keyboard.c
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.git] / usr.bin / systat / keyboard.c
1 /*-
2  * Copyright (c) 1980, 1992, 1993
3  *      The Regents of the University of California.  All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 4. Neither the name of the University nor the names of its contributors
14  *    may be used to endorse or promote products derived from this software
15  *    without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  */
29
30 #include <sys/cdefs.h>
31
32 __FBSDID("$FreeBSD$");
33
34 #ifdef lint
35 static const char sccsid[] = "@(#)keyboard.c    8.1 (Berkeley) 6/6/93";
36 #endif
37
38 #include <sys/select.h>
39 #include <sys/time.h>
40
41 #include <errno.h>
42 #include <ctype.h>
43 #include <stdlib.h>
44 #include <termios.h>
45 #include <unistd.h>
46
47 #include "systat.h"
48 #include "extern.h"
49
50 static char line[80];
51 static int keyboard_dispatch(int ch);
52
53 int
54 keyboard(void)
55 {
56         int ch, n;
57         struct timeval last, intvl, now, tm;
58         fd_set rfds;
59
60         /* Set initial timings */
61         gettimeofday(&last, NULL);
62         intvl.tv_sec = delay / 1000000;
63         intvl.tv_usec = delay % 1000000;
64         for (;;) {
65                 col = 0;
66                 move(CMDLINE, 0);
67                 for (;;) {
68                         /* Determine interval to sleep */
69                         (void)gettimeofday(&now, NULL);
70                         tm.tv_sec = last.tv_sec + intvl.tv_sec - now.tv_sec;
71                         tm.tv_usec = last.tv_usec + intvl.tv_usec - now.tv_usec;
72                         while (tm.tv_usec < 0) {
73                                 tm.tv_usec += 1000000;
74                                 tm.tv_sec--;
75                         }
76                         while (tm.tv_usec >= 1000000) {
77                                 tm.tv_usec -= 1000000;
78                                 tm.tv_sec++;
79                         }
80                         if (tm.tv_sec < 0) {
81                                 /* We have to update screen immediately */
82                                 display();
83                                 gettimeofday(&last, NULL);
84                                 continue;
85                         }
86
87                         /* Prepare select  */
88                         FD_ZERO(&rfds);
89                         FD_SET(STDIN_FILENO, &rfds);
90                         n = select(STDIN_FILENO + 1, &rfds, NULL, NULL, &tm);
91
92                         if (n > 0) {
93                                 /* Read event on stdin */
94                                 ch = getch();
95
96                                 if (keyboard_dispatch(ch) == 0) {
97                                         refresh();
98                                         continue;
99                                 }
100         
101                                 line[col] = '\0';
102                                 command(line + 1);
103                                 /* Refresh delay */
104                                 intvl.tv_sec = delay / 1000000;
105                                 intvl.tv_usec = delay % 1000000;
106                                 refresh();
107                                 break;
108                         }
109
110                         if (n < 0 && errno != EINTR)
111                                 exit(1);
112
113                         /* Timeout or signal. Call display another time */
114                         display();
115                         gettimeofday(&last, NULL);
116                 }
117         }
118 }
119
120 static int
121 keyboard_dispatch(int ch)
122 {
123
124         if (ch == ERR) {
125                 if (errno == EINTR)
126                         return 0;
127                 exit(1);
128         }
129         if (ch >= 'A' && ch <= 'Z')
130                 ch += 'a' - 'A';
131         if (col == 0) {
132                 if (ch == CTRL('l')) {
133                         wrefresh(curscr);
134                         return 0;
135                 }
136                 if (ch == CTRL('g')) {
137                         status();
138                         return 0;
139                 }
140                 if (ch != ':')
141                         return 0;
142                 move(CMDLINE, 0);
143                 clrtoeol();
144         }
145         if (ch == erasechar() && col > 0) {
146                 if (col == 1 && line[0] == ':')
147                         return 0;
148                 col--;
149                 goto doerase;
150         }
151         if (ch == CTRL('w') && col > 0) {
152                 while (--col >= 0 && isspace(line[col]))
153                         ;
154                 col++;
155                 while (--col >= 0 && !isspace(line[col]))
156                         if (col == 0 && line[0] == ':')
157                                 return 1;
158                 col++;
159                 goto doerase;
160         }
161         if (ch == killchar() && col > 0) {
162                 col = 0;
163                 if (line[0] == ':')
164                         col++;
165 doerase:
166                 move(CMDLINE, col);
167                 clrtoeol();
168                 return 0;
169         }
170         if (isprint(ch) || ch == ' ') {
171                 line[col] = ch;
172                 mvaddch(CMDLINE, col, ch);
173                 col++;
174         }
175
176         if (col == 0 || (ch != '\r' && ch != '\n'))
177                 return 0;
178
179         return 1;
180 }