Changes in / [2e07d27e:a1622091] in mainline
- Location:
- uspace
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/bdsh/input.c
r2e07d27e ra1622091 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 -
uspace/lib/libc/generic/io/console.c
r2e07d27e ra1622091 94 94 } 95 95 96 int console_get_pos(int phone, int *col, int *row) 97 { 98 ipcarg_t col_v; 99 ipcarg_t row_v; 100 int rc; 101 102 rc = async_req_0_2(phone, CONSOLE_GET_POS, &col_v, &row_v); 103 104 *col = (int) col_v; 105 *row = (int) row_v; 106 return rc; 107 } 108 96 109 void console_goto(int phone, int col, int row) 97 110 { -
uspace/lib/libc/include/io/console.h
r2e07d27e ra1622091 69 69 70 70 extern int console_get_size(int phone, int *cols, int *rows); 71 extern int console_get_pos(int phone, int *col, int *row); 71 72 extern void console_goto(int phone, int col, int row); 72 73 -
uspace/lib/libc/include/ipc/console.h
r2e07d27e ra1622091 43 43 CONSOLE_GET_COLOR_CAP, 44 44 CONSOLE_GET_EVENT, 45 CONSOLE_GET_POS, 45 46 CONSOLE_GOTO, 46 47 CONSOLE_CLEAR, -
uspace/srv/console/console.c
r2e07d27e ra1622091 601 601 IPC_GET_ARG2(call)); 602 602 break; 603 case CONSOLE_GET_POS: 604 arg1 = cons->scr.position_x; 605 arg2 = cons->scr.position_y; 606 break; 603 607 case CONSOLE_GET_SIZE: 604 608 arg1 = fb_info.cols;
Note:
See TracChangeset
for help on using the changeset viewer.