Changes in uspace/app/bdsh/input.c [ef8bcc6:19528516] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/bdsh/input.c
ref8bcc6 r19528516 47 47 #include "exec.h" 48 48 49 static void read_line(char *, int); 49 typedef struct { 50 wchar_t buffer[INPUT_MAX]; 51 int col0, row0; 52 int con_cols, con_rows; 53 int nc; 54 int pos; 55 } tinput_t; 56 57 typedef enum { 58 seek_cell, 59 seek_max 60 } seek_dist_t; 61 62 typedef enum { 63 seek_backward = -1, 64 seek_forward = 1 65 } seek_dir_t; 66 67 static tinput_t tinput; 68 69 static char *tinput_read(tinput_t *ti); 50 70 51 71 /* Tokenizes input from console, sees if the first word is a built-in, if so … … 99 119 } 100 120 101 static void read_line(char *buffer, int n) 121 static void tinput_display_tail(tinput_t *ti, int start, int pad) 122 { 123 int i; 124 125 console_goto(fphone(stdout), ti->col0 + start, ti->row0); 126 printf("%ls", ti->buffer + start); 127 for (i = 0; i < pad; ++i) 128 putchar(' '); 129 fflush(stdout); 130 } 131 132 static void tinput_position_caret(tinput_t *ti) 133 { 134 console_goto(fphone(stdout), ti->col0 + ti->pos, ti->row0); 135 } 136 137 static void tinput_insert_char(tinput_t *ti, wchar_t c) 138 { 139 int i; 140 141 if (ti->nc == INPUT_MAX) 142 return; 143 144 if (ti->col0 + ti->nc >= ti->con_cols - 1) 145 return; 146 147 for (i = ti->nc; i > ti->pos; --i) 148 ti->buffer[i] = ti->buffer[i - 1]; 149 150 ti->buffer[ti->pos] = c; 151 ti->pos += 1; 152 ti->nc += 1; 153 ti->buffer[ti->nc] = '\0'; 154 155 tinput_display_tail(ti, ti->pos - 1, 0); 156 tinput_position_caret(ti); 157 } 158 159 static void tinput_backspace(tinput_t *ti) 160 { 161 int i; 162 163 if (ti->pos == 0) 164 return; 165 166 for (i = ti->pos; i < ti->nc; ++i) 167 ti->buffer[i - 1] = ti->buffer[i]; 168 ti->pos -= 1; 169 ti->nc -= 1; 170 ti->buffer[ti->nc] = '\0'; 171 172 tinput_display_tail(ti, ti->pos, 1); 173 tinput_position_caret(ti); 174 } 175 176 static void tinput_delete(tinput_t *ti) 177 { 178 if (ti->pos == ti->nc) 179 return; 180 181 ti->pos += 1; 182 tinput_backspace(ti); 183 } 184 185 static void tinput_seek(tinput_t *ti, seek_dir_t dir, seek_dist_t dist) 186 { 187 switch (dist) { 188 case seek_cell: 189 ti->pos += dir; 190 break; 191 case seek_max: 192 if (dir == seek_backward) 193 ti->pos = 0; 194 else 195 ti->pos = ti->nc; 196 break; 197 } 198 199 if (ti->pos < 0) ti->pos = 0; 200 if (ti->pos > ti->nc) ti->pos = ti->nc; 201 202 tinput_position_caret(ti); 203 } 204 205 static char *tinput_read(tinput_t *ti) 102 206 { 103 207 console_event_t ev; 104 size_t offs, otmp; 105 wchar_t dec; 106 107 offs = 0; 208 char *str; 209 210 fflush(stdout); 211 212 if (console_get_size(fphone(stdin), &ti->con_cols, &ti->con_rows) != EOK) 213 return NULL; 214 if (console_get_pos(fphone(stdin), &ti->col0, &ti->row0) != EOK) 215 return NULL; 216 217 ti->pos = 0; 218 ti->nc = 0; 219 108 220 while (true) { 109 221 fflush(stdout); 110 222 if (!console_get_event(fphone(stdin), &ev)) 111 return ;223 return NULL; 112 224 113 225 if (ev.type != KEY_PRESS) 114 226 continue; 115 116 if (ev.key == KC_ENTER || ev.key == KC_NENTER) 117 break; 118 if (ev.key == KC_BACKSPACE) { 119 if (offs > 0) { 120 /* 121 * Back up until we reach valid start of 122 * character. 123 */ 124 while (offs > 0) { 125 --offs; otmp = offs; 126 dec = str_decode(buffer, &otmp, n); 127 if (dec != U_SPECIAL) 128 break; 129 } 130 putchar('\b'); 131 } 227 228 if ((ev.mods & (KM_CTRL | KM_ALT | KM_SHIFT)) != 0) 132 229 continue; 230 231 switch(ev.key) { 232 case KC_ENTER: 233 case KC_NENTER: 234 goto done; 235 case KC_BACKSPACE: 236 tinput_backspace(ti); 237 break; 238 case KC_DELETE: 239 tinput_delete(ti); 240 break; 241 case KC_LEFT: 242 tinput_seek(ti, seek_backward, seek_cell); 243 break; 244 case KC_RIGHT: 245 tinput_seek(ti, seek_forward, seek_cell); 246 247 break; 248 case KC_HOME: 249 tinput_seek(ti, seek_backward, seek_max); 250 break; 251 case KC_END: 252 tinput_seek(ti, seek_forward, seek_max); 253 break; 133 254 } 134 255 if (ev.c >= ' ') { 135 if (chr_encode(ev.c, buffer, &offs, n - 1) == EOK) 136 putchar(ev.c); 256 tinput_insert_char(ti, ev.c); 137 257 } 138 258 } 259 260 done: 139 261 putchar('\n'); 140 buffer[offs] = '\0'; 141 } 142 143 /* TODO: 144 * Implement something like editline() / readline(), if even 145 * just for command history and making arrows work. */ 262 263 ti->buffer[ti->nc] = '\0'; 264 str = malloc(STR_BOUNDS(ti->nc) + 1); 265 if (str == NULL) 266 return NULL; 267 268 wstr_nstr(str, ti->buffer, STR_BOUNDS(ti->nc) + 1); 269 270 return str; 271 } 272 146 273 void get_input(cliuser_t *usr) 147 274 { 148 char line[INPUT_MAX];275 char *str; 149 276 150 277 fflush(stdout); … … 154 281 console_set_style(fphone(stdout), STYLE_NORMAL); 155 282 156 read_line(line, INPUT_MAX); 157 /* Make sure we don't have rubbish or a C/R happy user */ 158 if (str_cmp(line, "") == 0 || str_cmp(line, "\n") == 0) 159 return; 160 usr->line = str_dup(line); 161 283 str = tinput_read(&tinput); 284 285 /* Check for empty input. */ 286 if (str_cmp(str, "") == 0) { 287 free(str); 288 return; 289 } 290 291 usr->line = str; 162 292 return; 163 293 } 164
Note:
See TracChangeset
for help on using the changeset viewer.