aboutsummaryrefslogtreecommitdiff
path: root/libbb/read_key.c
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2009-05-17 16:44:54 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2009-05-17 16:44:54 +0200
commit020f40693a08b836abdea74f3823a0bce0378ec5 (patch)
tree4ae11c9b2156cccc1af8904c11c195b25b2886b0 /libbb/read_key.c
parent071ede1e5de784820f39c2546000c08d74b12f6d (diff)
downloadbusybox-w32-020f40693a08b836abdea74f3823a0bce0378ec5.tar.gz
busybox-w32-020f40693a08b836abdea74f3823a0bce0378ec5.tar.bz2
busybox-w32-020f40693a08b836abdea74f3823a0bce0378ec5.zip
line editing: add an option to emit ESC [ 6 n and use results
This makes line editing able to recognize case when cursor was not at the beginning of the line. It may also be adapted later to find out display size (serial line users would love it). Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'libbb/read_key.c')
-rw-r--r--libbb/read_key.c57
1 files changed, 49 insertions, 8 deletions
diff --git a/libbb/read_key.c b/libbb/read_key.c
index fd100b0ec..3771045d2 100644
--- a/libbb/read_key.c
+++ b/libbb/read_key.c
@@ -9,7 +9,7 @@
9 */ 9 */
10#include "libbb.h" 10#include "libbb.h"
11 11
12int FAST_FUNC read_key(int fd, smalluint *nbuffered, char *buffer) 12int64_t FAST_FUNC read_key(int fd, char *buffer)
13{ 13{
14 struct pollfd pfd; 14 struct pollfd pfd;
15 const char *seq; 15 const char *seq;
@@ -67,9 +67,7 @@ int FAST_FUNC read_key(int fd, smalluint *nbuffered, char *buffer)
67 }; 67 };
68 68
69 errno = 0; 69 errno = 0;
70 n = 0; 70 n = (unsigned char) *buffer++;
71 if (nbuffered)
72 n = *nbuffered;
73 if (n == 0) { 71 if (n == 0) {
74 /* If no data, block waiting for input. If we read more 72 /* If no data, block waiting for input. If we read more
75 * than the minimal ESC sequence size, the "n=0" below 73 * than the minimal ESC sequence size, the "n=0" below
@@ -148,11 +146,54 @@ int FAST_FUNC read_key(int fd, smalluint *nbuffered, char *buffer)
148 } 146 }
149 } 147 }
150 /* We did not find matching sequence, it was a bare ESC. 148 /* We did not find matching sequence, it was a bare ESC.
151 * We possibly read and stored more input in buffer[] 149 * We possibly read and stored more input in buffer[] by now. */
152 * by now. */ 150
151 /* Try to decipher "ESC [ NNN ; NNN R" sequence */
152 if (ENABLE_FEATURE_EDITING_ASK_TERMINAL
153 && n != 0
154 && buffer[0] == '['
155 ) {
156 char *end;
157 unsigned long row, col;
158
159 while (n < KEYCODE_BUFFER_SIZE-1) { /* 1 for cnt */
160 if (safe_poll(&pfd, 1, 50) == 0) {
161 /* No more data! */
162 break;
163 }
164 errno = 0;
165 if (safe_read(fd, buffer + n, 1) <= 0) {
166 /* If EAGAIN, then fd is O_NONBLOCK and poll lied:
167 * in fact, there is no data. */
168 if (errno != EAGAIN)
169 c = -1; /* otherwise it's EOF/error */
170 goto ret;
171 }
172 if (buffer[n++] == 'R')
173 goto got_R;
174 }
175 goto ret;
176 got_R:
177 if (!isdigit(buffer[1]))
178 goto ret;
179 row = strtoul(buffer + 1, &end, 10);
180 if (*end != ';' || !isdigit(end[1]))
181 goto ret;
182 col = strtoul(end + 1, &end, 10);
183 if (*end != 'R')
184 goto ret;
185 if (row < 1 || col < 1 || (row | col) > 0x7fff)
186 goto ret;
187
188 buffer[-1] = 0;
189
190 /* Pack into "1 <row15bits> <col16bits>" 32-bit sequence */
191 c = (((-1 << 15) | row) << 16) | col;
192 /* Return it in high-order word */
193 return ((int64_t) c << 32) | (uint32_t)KEYCODE_CURSOR_POS;
194 }
153 195
154 ret: 196 ret:
155 if (nbuffered) 197 buffer[-1] = n;
156 *nbuffered = n;
157 return c; 198 return c;
158} 199}