]> gitweb.fperrin.net Git - iftop.git/blob - edline.c
Import iftop-1.0pre4
[iftop.git] / edline.c
1 /*
2  * edline.c:
3  * Text input on a line of the screen.
4  *
5  */
6
7 static const char rcsid[] = "$Id: edline.c,v 1.2 2002/11/04 12:27:35 chris Exp $";
8
9 #include <ctype.h>
10 #include <curses.h>
11 #include <string.h>
12
13 #include "iftop.h"
14
15 static int min(const int a, const int b) {
16     return a < b ? a : b;
17 }
18
19 /* edline:
20  * Display on line linenum of the screen the prompt and allow the user to input
21  * a line of text, whose initial value is as supplied. */
22 char *edline(int linenum, const char *prompt, const char *initial) {
23     int xstart, slen, off = 0, pos, i, c;
24     char *str;
25     
26     xstart = strlen(prompt) + 2;
27
28     if (initial) {
29         str = xmalloc(slen = strlen(initial) * 2 + 1);
30         strcpy(str, initial);
31     } else {
32         str = xmalloc(slen = 256);
33         *str = 0;
34     }
35
36     pos = strlen(str);
37
38     do {
39         c = getch();
40         switch (c) {
41             case KEY_DL:
42             case 21:    /* ^U */
43                 *str = 0;
44                 pos = 0;
45                 break;
46
47             case KEY_LEFT:
48                 --pos;
49                 if (pos < 0) {
50                     beep();
51                     pos = 0;
52                 }
53                 break;
54
55             case KEY_RIGHT:
56                 ++pos;
57                 if (pos > strlen(str)) {
58                     beep();
59                     pos = strlen(str);
60                 }
61                 break;
62
63             case KEY_HOME:
64             case 1:         /* ^A */
65                 pos = 0;
66                 break;
67
68             case KEY_END:
69             case 5:         /* ^E */
70                 pos = strlen(str);
71                 break;
72
73             case KEY_DC:
74                 if (pos == strlen(str))
75                     beep();
76                 else
77                     memmove(str + pos, str + pos + 1, strlen(str + pos + 1) + 1);
78                 break;
79
80             case KEY_BACKSPACE:
81                 if (pos == 0)
82                     beep();
83                 else {
84                     memmove(str + pos - 1, str + pos, strlen(str + pos) + 1);
85                     --pos;
86                 }
87                 break;
88
89             case 23:    /* ^W */
90                 for (i = pos; i > 0; --i)
91                     if (!isspace((int)str[i])) break;
92                 for (; i > 0; --i)
93                     if (isspace((int)str[i])) break;
94                 if (i != pos) {
95                     memmove(str + i, str + pos, strlen(str + pos) + 1);
96                     pos = i;
97                 }
98                 break;
99
100             case ERR:
101                 break;
102
103             default:
104                 if (isprint(c) && c != '\t') {
105                     if (strlen(str) == slen - 1)
106                         str = xrealloc(str, slen *= 2);
107                     memmove(str + pos + 1, str + pos, strlen(str + pos) + 1);
108                     str[pos++] = (char)c;
109                 } else
110                     beep();
111                 break;
112         }
113
114         /* figure out the offset to use for the string */
115         off = 0;
116         if (pos > COLS - xstart - 1)
117             off = pos - (COLS - xstart - 1);
118         
119         /* display the string */
120         mvaddstr(linenum, 0, prompt);
121         addstr("> ");
122         addnstr(str + off, min(strlen(str + off), COLS - xstart - 1));
123         clrtoeol();
124         move(linenum, xstart + pos - off);
125         refresh();
126     } while (c != KEY_ENTER && c != '\r' && c != '\x1b' && c != 7 /* ^G */);
127
128     if (c == KEY_ENTER || c == '\r')
129         /* Success */
130         return str;
131     else {
132         xfree(str);
133         return NULL;
134     }
135 }