Changes in uspace/app/bdsh/input.c [19528516:ef8bcc6] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/bdsh/input.c
r19528516 ref8bcc6 47 47 #include "exec.h" 48 48 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); 49 static void read_line(char *, int); 70 50 71 51 /* Tokenizes input from console, sees if the first word is a built-in, if so … … 119 99 } 120 100 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) 101 static void read_line(char *buffer, int n) 206 102 { 207 103 console_event_t ev; 208 char *str; 104 size_t offs, otmp; 105 wchar_t dec; 209 106 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 107 offs = 0; 220 108 while (true) { 221 109 fflush(stdout); 222 110 if (!console_get_event(fphone(stdin), &ev)) 223 return NULL;111 return; 224 112 225 113 if (ev.type != KEY_PRESS) 226 114 continue; 227 228 if ((ev.mods & (KM_CTRL | KM_ALT | KM_SHIFT)) != 0) 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 } 229 132 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;254 133 } 255 134 if (ev.c >= ' ') { 256 tinput_insert_char(ti, ev.c); 135 if (chr_encode(ev.c, buffer, &offs, n - 1) == EOK) 136 putchar(ev.c); 257 137 } 258 138 } 259 260 done:261 139 putchar('\n'); 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; 140 buffer[offs] = '\0'; 271 141 } 272 142 143 /* TODO: 144 * Implement something like editline() / readline(), if even 145 * just for command history and making arrows work. */ 273 146 void get_input(cliuser_t *usr) 274 147 { 275 char *str;148 char line[INPUT_MAX]; 276 149 277 150 fflush(stdout); … … 281 154 console_set_style(fphone(stdout), STYLE_NORMAL); 282 155 283 str = tinput_read(&tinput); 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); 284 161 285 /* Check for empty input. */286 if (str_cmp(str, "") == 0) {287 free(str);288 return;289 }290 291 usr->line = str;292 162 return; 293 163 } 164
Note:
See TracChangeset
for help on using the changeset viewer.