source: mainline/uspace/app/bdsh/input.c@ 86018c1

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 86018c1 was bc77bfa, checked in by Jiri Svoboda <jiri@…>, 16 years ago

Squash bugs.

  • Property mode set to 100644
File size: 16.4 KB
RevLine 
[216d6fc]1/* Copyright (c) 2008, Tim Post <tinkertim@gmail.com>
2 * All rights reserved.
3 * Copyright (c) 2008, Jiri Svoboda - All Rights Reserved
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * Redistributions of source code must retain the above copyright notice, this
9 * list of conditions and the following disclaimer.
10 *
11 * Redistributions in binary form must reproduce the above copyright notice,
12 * this list of conditions and the following disclaimer in the documentation
13 * and/or other materials provided with the distribution.
14 *
15 * Neither the name of the original program's authors nor the names of its
16 * contributors may be used to endorse or promote products derived from this
17 * software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31
32#include <stdio.h>
33#include <stdlib.h>
34#include <string.h>
[73878c1]35#include <io/console.h>
36#include <io/keycode.h>
37#include <io/style.h>
[7e0cb78]38#include <io/color.h>
[3bf907a]39#include <vfs/vfs.h>
[371a012]40#include <clipboard.h>
[f1b37d6]41#include <macros.h>
[6071a8f]42#include <errno.h>
[da2bd08]43#include <assert.h>
[6071a8f]44#include <bool.h>
[216d6fc]45
46#include "config.h"
47#include "util.h"
48#include "scli.h"
49#include "input.h"
50#include "errors.h"
51#include "exec.h"
52
[da2bd08]53#define HISTORY_LEN 10
54
[ed372da]55/** Text input field. */
[19528516]56typedef struct {
[ed372da]57 /** Buffer holding text currently being edited */
[51ea01e]58 wchar_t buffer[INPUT_MAX + 1];
[ed372da]59 /** Screen coordinates of the top-left corner of the text field */
[19528516]60 int col0, row0;
[ed372da]61 /** Screen dimensions */
[19528516]62 int con_cols, con_rows;
[ed372da]63 /** Number of characters in @c buffer */
[19528516]64 int nc;
[ed372da]65 /** Caret position within buffer */
[19528516]66 int pos;
[ed372da]67 /** Selection mark position within buffer */
[7e0cb78]68 int sel_start;
[da2bd08]69
[ed372da]70 /** History (dynamically allocated strings) */
[da2bd08]71 char *history[1 + HISTORY_LEN];
[ed372da]72 /** Number of entries in @c history, not counting [0] */
[da2bd08]73 int hnum;
[ed372da]74 /** Current position in history */
[da2bd08]75 int hpos;
[ed372da]76 /** Exit flag */
[7e0cb78]77 bool done;
[19528516]78} tinput_t;
79
[ed372da]80/** Seek direction */
[19528516]81typedef enum {
82 seek_backward = -1,
83 seek_forward = 1
84} seek_dir_t;
85
86static tinput_t tinput;
87
88static char *tinput_read(tinput_t *ti);
[f1b37d6]89static void tinput_insert_string(tinput_t *ti, const char *str);
[7e0cb78]90static void tinput_sel_get_bounds(tinput_t *ti, int *sa, int *sb);
91static bool tinput_sel_active(tinput_t *ti);
[cedd33b]92static void tinput_sel_all(tinput_t *ti);
[7e0cb78]93static void tinput_sel_delete(tinput_t *ti);
94static void tinput_key_ctrl(tinput_t *ti, console_event_t *ev);
95static void tinput_key_shift(tinput_t *ti, console_event_t *ev);
96static void tinput_key_ctrl_shift(tinput_t *ti, console_event_t *ev);
97static void tinput_key_unmod(tinput_t *ti, console_event_t *ev);
98static void tinput_pre_seek(tinput_t *ti, bool shift_held);
99static void tinput_post_seek(tinput_t *ti, bool shift_held);
[88944695]100
[216d6fc]101/* Tokenizes input from console, sees if the first word is a built-in, if so
102 * invokes the built-in entry point (a[0]) passing all arguments in a[] to
103 * the handler */
104int tok_input(cliuser_t *usr)
105{
106 char *cmd[WORD_MAX];
107 int n = 0, i = 0;
108 int rc = 0;
109 char *tmp;
110
111 if (NULL == usr->line)
112 return CL_EFAIL;
113
[095003a8]114 tmp = str_dup(usr->line);
[216d6fc]115
[4cc0c9ee]116 cmd[n] = strtok(tmp, " ");
[216d6fc]117 while (cmd[n] && n < WORD_MAX) {
[4cc0c9ee]118 cmd[++n] = strtok(NULL, " ");
[216d6fc]119 }
120
121 /* We have rubbish */
122 if (NULL == cmd[0]) {
123 rc = CL_ENOENT;
124 goto finit;
125 }
126
[d752cf4]127 /* Its a builtin command ? */
[216d6fc]128 if ((i = (is_builtin(cmd[0]))) > -1) {
129 rc = run_builtin(i, cmd, usr);
130 goto finit;
[d752cf4]131 /* Its a module ? */
[216d6fc]132 } else if ((i = (is_module(cmd[0]))) > -1) {
133 rc = run_module(i, cmd);
134 goto finit;
135 }
136
[d752cf4]137 /* See what try_exec thinks of it */
138 rc = try_exec(cmd[0], cmd);
139
[216d6fc]140finit:
141 if (NULL != usr->line) {
142 free(usr->line);
143 usr->line = (char *) NULL;
144 }
145 if (NULL != tmp)
146 free(tmp);
147
148 return rc;
149}
150
[19528516]151static void tinput_display_tail(tinput_t *ti, int start, int pad)
152{
[7e0cb78]153 static wchar_t dbuf[INPUT_MAX + 1];
154 int sa, sb;
155 int i, p;
156
157 tinput_sel_get_bounds(ti, &sa, &sb);
[19528516]158
[e228280]159 console_goto(fphone(stdout), (ti->col0 + start) % ti->con_cols,
160 ti->row0 + (ti->col0 + start) / ti->con_cols);
[7e0cb78]161 console_set_color(fphone(stdout), COLOR_BLACK, COLOR_WHITE, 0);
162
163 p = start;
164 if (p < sa) {
165 memcpy(dbuf, ti->buffer + p, (sa - p) * sizeof(wchar_t));
166 dbuf[sa - p] = '\0';
167 printf("%ls", dbuf);
168 p = sa;
169 }
170
171 if (p < sb) {
172 fflush(stdout);
173 console_set_color(fphone(stdout), COLOR_BLACK, COLOR_RED, 0);
174 memcpy(dbuf, ti->buffer + p,
175 (sb - p) * sizeof(wchar_t));
176 dbuf[sb - p] = '\0';
177 printf("%ls", dbuf);
178 p = sb;
179 }
180
181 fflush(stdout);
182 console_set_color(fphone(stdout), COLOR_BLACK, COLOR_WHITE, 0);
183
184 if (p < ti->nc) {
185 memcpy(dbuf, ti->buffer + p,
186 (ti->nc - p) * sizeof(wchar_t));
187 dbuf[ti->nc - p] = '\0';
188 printf("%ls", dbuf);
189 }
190
[19528516]191 for (i = 0; i < pad; ++i)
192 putchar(' ');
193 fflush(stdout);
194}
195
[da2bd08]196static char *tinput_get_str(tinput_t *ti)
197{
[b67c7d64]198 return wstr_to_astr(ti->buffer);
[da2bd08]199}
200
[19528516]201static void tinput_position_caret(tinput_t *ti)
202{
[e228280]203 console_goto(fphone(stdout), (ti->col0 + ti->pos) % ti->con_cols,
204 ti->row0 + (ti->col0 + ti->pos) / ti->con_cols);
205}
206
207/** Update row0 in case the screen could have scrolled. */
208static void tinput_update_origin(tinput_t *ti)
209{
210 int width, rows;
211
212 width = ti->col0 + ti->nc;
213 rows = (width / ti->con_cols) + 1;
[ed372da]214
[e228280]215 /* Update row0 if the screen scrolled. */
216 if (ti->row0 + rows > ti->con_rows)
217 ti->row0 = ti->con_rows - rows;
[19528516]218}
219
220static void tinput_insert_char(tinput_t *ti, wchar_t c)
221{
222 int i;
[e228280]223 int new_width, new_height;
[19528516]224
225 if (ti->nc == INPUT_MAX)
226 return;
227
[e228280]228 new_width = ti->col0 + ti->nc + 1;
229 if (new_width % ti->con_cols == 0) {
230 /* Advancing to new line. */
231 new_height = (new_width / ti->con_cols) + 1;
232 if (new_height >= ti->con_rows)
233 return; /* Disallow text longer than 1 page for now. */
234 }
[19528516]235
236 for (i = ti->nc; i > ti->pos; --i)
237 ti->buffer[i] = ti->buffer[i - 1];
238
239 ti->buffer[ti->pos] = c;
240 ti->pos += 1;
241 ti->nc += 1;
242 ti->buffer[ti->nc] = '\0';
[7e0cb78]243 ti->sel_start = ti->pos;
[19528516]244
245 tinput_display_tail(ti, ti->pos - 1, 0);
[e228280]246 tinput_update_origin(ti);
[19528516]247 tinput_position_caret(ti);
248}
249
[f1b37d6]250static void tinput_insert_string(tinput_t *ti, const char *str)
251{
252 int i;
253 int new_width, new_height;
254 int ilen;
255 wchar_t c;
256 size_t off;
257
[cedd33b]258 ilen = min((ssize_t) str_length(str), INPUT_MAX - ti->nc);
[f1b37d6]259 if (ilen == 0)
260 return;
261
262 new_width = ti->col0 + ti->nc + ilen;
263 new_height = (new_width / ti->con_cols) + 1;
264 if (new_height >= ti->con_rows)
265 return; /* Disallow text longer than 1 page for now. */
266
267 for (i = ti->nc - 1; i >= ti->pos; --i)
268 ti->buffer[i + ilen] = ti->buffer[i];
269
270 off = 0; i = 0;
271 while (i < ilen) {
272 c = str_decode(str, &off, STR_NO_LIMIT);
273 if (c == '\0')
274 break;
275
276 /* Filter out non-printable chars. */
277 if (c < 32)
278 c = 32;
279
[bc77bfa]280 ti->buffer[ti->pos + i] = c;
281 ++i;
[f1b37d6]282 }
283
284 ti->pos += ilen;
285 ti->nc += ilen;
286 ti->buffer[ti->nc] = '\0';
287 ti->sel_start = ti->pos;
288
289 tinput_display_tail(ti, ti->pos - ilen, 0);
290 tinput_update_origin(ti);
291 tinput_position_caret(ti);
292}
293
[19528516]294static void tinput_backspace(tinput_t *ti)
295{
296 int i;
297
[7e0cb78]298 if (tinput_sel_active(ti)) {
299 tinput_sel_delete(ti);
300 return;
301 }
[ed372da]302
[19528516]303 if (ti->pos == 0)
304 return;
305
306 for (i = ti->pos; i < ti->nc; ++i)
307 ti->buffer[i - 1] = ti->buffer[i];
308 ti->pos -= 1;
309 ti->nc -= 1;
310 ti->buffer[ti->nc] = '\0';
[7e0cb78]311 ti->sel_start = ti->pos;
[19528516]312
313 tinput_display_tail(ti, ti->pos, 1);
314 tinput_position_caret(ti);
315}
316
317static void tinput_delete(tinput_t *ti)
318{
[7e0cb78]319 if (tinput_sel_active(ti)) {
320 tinput_sel_delete(ti);
321 return;
322 }
323
[19528516]324 if (ti->pos == ti->nc)
325 return;
326
327 ti->pos += 1;
[7e0cb78]328 ti->sel_start = ti->pos;
329
[19528516]330 tinput_backspace(ti);
331}
332
[7e0cb78]333static void tinput_seek_cell(tinput_t *ti, seek_dir_t dir, bool shift_held)
[19528516]334{
[7e0cb78]335 tinput_pre_seek(ti, shift_held);
336
[025759c]337 if (dir == seek_forward) {
338 if (ti->pos < ti->nc)
339 ti->pos += 1;
340 } else {
341 if (ti->pos > 0)
342 ti->pos -= 1;
[19528516]343 }
[025759c]344
[7e0cb78]345 tinput_post_seek(ti, shift_held);
[025759c]346}
347
[7e0cb78]348static void tinput_seek_word(tinput_t *ti, seek_dir_t dir, bool shift_held)
[025759c]349{
[7e0cb78]350 tinput_pre_seek(ti, shift_held);
351
[025759c]352 if (dir == seek_forward) {
353 if (ti->pos == ti->nc)
354 return;
355
356 while (1) {
357 ti->pos += 1;
358
359 if (ti->pos == ti->nc)
360 break;
361
362 if (ti->buffer[ti->pos - 1] == ' ' &&
363 ti->buffer[ti->pos] != ' ')
364 break;
365 }
366 } else {
367 if (ti->pos == 0)
368 return;
369
370 while (1) {
371 ti->pos -= 1;
372
373 if (ti->pos == 0)
374 break;
375
376 if (ti->buffer[ti->pos - 1] == ' ' &&
377 ti->buffer[ti->pos] != ' ')
378 break;
379 }
380
381 }
382
[7e0cb78]383 tinput_post_seek(ti, shift_held);
[025759c]384}
385
[7e0cb78]386static void tinput_seek_vertical(tinput_t *ti, seek_dir_t dir, bool shift_held)
[e228280]387{
[7e0cb78]388 tinput_pre_seek(ti, shift_held);
389
[3041fef1]390 if (dir == seek_forward) {
391 if (ti->pos + ti->con_cols <= ti->nc)
392 ti->pos = ti->pos + ti->con_cols;
393 } else {
394 if (ti->pos - ti->con_cols >= 0)
395 ti->pos = ti->pos - ti->con_cols;
396 }
[e228280]397
[7e0cb78]398 tinput_post_seek(ti, shift_held);
[e228280]399}
400
[7e0cb78]401static void tinput_seek_max(tinput_t *ti, seek_dir_t dir, bool shift_held)
[025759c]402{
[7e0cb78]403 tinput_pre_seek(ti, shift_held);
404
[025759c]405 if (dir == seek_backward)
406 ti->pos = 0;
407 else
408 ti->pos = ti->nc;
[19528516]409
[7e0cb78]410 tinput_post_seek(ti, shift_held);
411}
412
413static void tinput_pre_seek(tinput_t *ti, bool shift_held)
414{
415 if (tinput_sel_active(ti) && !shift_held) {
416 /* Unselect and redraw. */
417 ti->sel_start = ti->pos;
418 tinput_display_tail(ti, 0, 0);
419 tinput_position_caret(ti);
420 }
421}
422
423static void tinput_post_seek(tinput_t *ti, bool shift_held)
424{
425 if (shift_held) {
426 /* Selecting text. Need redraw. */
427 tinput_display_tail(ti, 0, 0);
428 } else {
429 /* Shift not held. Keep selection empty. */
430 ti->sel_start = ti->pos;
431 }
[19528516]432 tinput_position_caret(ti);
433}
434
[da2bd08]435static void tinput_history_insert(tinput_t *ti, char *str)
436{
437 int i;
438
439 if (ti->hnum < HISTORY_LEN) {
440 ti->hnum += 1;
441 } else {
442 if (ti->history[HISTORY_LEN] != NULL)
443 free(ti->history[HISTORY_LEN]);
444 }
445
446 for (i = ti->hnum; i > 1; --i)
447 ti->history[i] = ti->history[i - 1];
448
449 ti->history[1] = str_dup(str);
450
451 if (ti->history[0] != NULL) {
452 free(ti->history[0]);
453 ti->history[0] = NULL;
454 }
455}
456
457static void tinput_set_str(tinput_t *ti, char *str)
458{
459 str_to_wstr(ti->buffer, INPUT_MAX, str);
460 ti->nc = wstr_length(ti->buffer);
461 ti->pos = ti->nc;
[7e0cb78]462 ti->sel_start = ti->pos;
463}
464
465static void tinput_sel_get_bounds(tinput_t *ti, int *sa, int *sb)
466{
467 if (ti->sel_start < ti->pos) {
468 *sa = ti->sel_start;
469 *sb = ti->pos;
470 } else {
471 *sa = ti->pos;
472 *sb = ti->sel_start;
473 }
474}
475
476static bool tinput_sel_active(tinput_t *ti)
477{
478 return ti->sel_start != ti->pos;
479}
480
[cedd33b]481static void tinput_sel_all(tinput_t *ti)
482{
483 ti->sel_start = 0;
484 ti->pos = ti->nc;
485 tinput_display_tail(ti, 0, 0);
486 tinput_position_caret(ti);
487}
488
[7e0cb78]489static void tinput_sel_delete(tinput_t *ti)
490{
491 int sa, sb;
492
493 tinput_sel_get_bounds(ti, &sa, &sb);
494 if (sa == sb)
495 return;
496
497 memmove(ti->buffer + sa, ti->buffer + sb,
498 (ti->nc - sb) * sizeof(wchar_t));
499 ti->pos = ti->sel_start = sa;
500 ti->nc -= (sb - sa);
501 ti->buffer[ti->nc] = '\0';
502
503 tinput_display_tail(ti, sa, sb - sa);
504 tinput_position_caret(ti);
[da2bd08]505}
506
[371a012]507static void tinput_sel_copy_to_cb(tinput_t *ti)
508{
509 int sa, sb;
510 wchar_t tmp_c;
511 char *str;
512
513 tinput_sel_get_bounds(ti, &sa, &sb);
514
515 if (sb < ti->nc) {
516 tmp_c = ti->buffer[sb];
517 ti->buffer[sb] = '\0';
518 }
519
520 str = wstr_to_astr(ti->buffer + sa);
521
522 if (sb < ti->nc)
523 ti->buffer[sb] = tmp_c;
524
525 if (str == NULL)
526 goto error;
527
528 if (clipboard_put_str(str) != EOK)
529 goto error;
530
531 free(str);
532 return;
533error:
534 return;
535 /* TODO: Give the user some warning. */
536}
537
538static void tinput_paste_from_cb(tinput_t *ti)
539{
540 char *str;
541 int rc;
542
543 rc = clipboard_get_str(&str);
544 if (rc != EOK || str == NULL)
545 return; /* TODO: Give the user some warning. */
546
[f1b37d6]547 tinput_insert_string(ti, str);
[371a012]548 free(str);
549}
550
[da2bd08]551static void tinput_history_seek(tinput_t *ti, int offs)
552{
553 int pad;
554
555 if (ti->hpos + offs < 0 || ti->hpos + offs > ti->hnum)
556 return;
557
558 if (ti->history[ti->hpos] != NULL) {
559 free(ti->history[ti->hpos]);
560 ti->history[ti->hpos] = NULL;
561 }
562
563 ti->history[ti->hpos] = tinput_get_str(ti);
564 ti->hpos += offs;
565
566 pad = ti->nc - str_length(ti->history[ti->hpos]);
567 if (pad < 0) pad = 0;
568
569 tinput_set_str(ti, ti->history[ti->hpos]);
570 tinput_display_tail(ti, 0, pad);
[e228280]571 tinput_update_origin(ti);
[da2bd08]572 tinput_position_caret(ti);
573}
574
[ed372da]575/** Initialize text input field.
576 *
577 * Must be called before using the field. It clears the history.
578 */
[da2bd08]579static void tinput_init(tinput_t *ti)
580{
581 ti->hnum = 0;
582 ti->hpos = 0;
583 ti->history[0] = NULL;
584}
585
[ed372da]586/** Read in one line of input. */
[19528516]587static char *tinput_read(tinput_t *ti)
[216d6fc]588{
[73878c1]589 console_event_t ev;
[19528516]590 char *str;
591
592 fflush(stdout);
593
594 if (console_get_size(fphone(stdin), &ti->con_cols, &ti->con_rows) != EOK)
595 return NULL;
596 if (console_get_pos(fphone(stdin), &ti->col0, &ti->row0) != EOK)
597 return NULL;
598
[7e0cb78]599 ti->pos = ti->sel_start = 0;
[19528516]600 ti->nc = 0;
[fd34f4e]601 ti->buffer[0] = '\0';
[7e0cb78]602 ti->done = false;
[216d6fc]603
[7e0cb78]604 while (!ti->done) {
[56fa418]605 fflush(stdout);
[73878c1]606 if (!console_get_event(fphone(stdin), &ev))
[19528516]607 return NULL;
[7e0cb78]608
[73878c1]609 if (ev.type != KEY_PRESS)
[56fa418]610 continue;
[19528516]611
[025759c]612 if ((ev.mods & KM_CTRL) != 0 &&
613 (ev.mods & (KM_ALT | KM_SHIFT)) == 0) {
[7e0cb78]614 tinput_key_ctrl(ti, &ev);
615 }
616
617 if ((ev.mods & KM_SHIFT) != 0 &&
618 (ev.mods & (KM_CTRL | KM_ALT)) == 0) {
619 tinput_key_shift(ti, &ev);
620 }
621
622 if ((ev.mods & KM_CTRL) != 0 &&
623 (ev.mods & KM_SHIFT) != 0 &&
624 (ev.mods & KM_ALT) == 0) {
625 tinput_key_ctrl_shift(ti, &ev);
[025759c]626 }
[19528516]627
[025759c]628 if ((ev.mods & (KM_CTRL | KM_ALT | KM_SHIFT)) == 0) {
[7e0cb78]629 tinput_key_unmod(ti, &ev);
[216d6fc]630 }
[025759c]631
[56fa418]632 if (ev.c >= ' ') {
[7e0cb78]633 tinput_sel_delete(ti);
[19528516]634 tinput_insert_char(ti, ev.c);
[38c64e8]635 }
[216d6fc]636 }
[19528516]637
[e228280]638 ti->pos = ti->nc;
639 tinput_position_caret(ti);
[216d6fc]640 putchar('\n');
[19528516]641
[da2bd08]642 str = tinput_get_str(ti);
643 if (str_cmp(str, "") != 0)
644 tinput_history_insert(ti, str);
[19528516]645
[da2bd08]646 ti->hpos = 0;
[19528516]647
648 return str;
[216d6fc]649}
650
[7e0cb78]651static void tinput_key_ctrl(tinput_t *ti, console_event_t *ev)
652{
653 switch (ev->key) {
654 case KC_LEFT:
655 tinput_seek_word(ti, seek_backward, false);
656 break;
657 case KC_RIGHT:
658 tinput_seek_word(ti, seek_forward, false);
659 break;
660 case KC_UP:
661 tinput_seek_vertical(ti, seek_backward, false);
662 break;
663 case KC_DOWN:
664 tinput_seek_vertical(ti, seek_forward, false);
665 break;
[cedd33b]666 case KC_X:
667 tinput_sel_copy_to_cb(ti);
668 tinput_sel_delete(ti);
669 break;
[371a012]670 case KC_C:
671 tinput_sel_copy_to_cb(ti);
672 break;
673 case KC_V:
[bc77bfa]674 tinput_sel_delete(ti);
[371a012]675 tinput_paste_from_cb(ti);
676 break;
[cedd33b]677 case KC_A:
678 tinput_sel_all(ti);
679 break;
[7e0cb78]680 default:
681 break;
682 }
683}
684
685static void tinput_key_ctrl_shift(tinput_t *ti, console_event_t *ev)
686{
687 switch (ev->key) {
688 case KC_LEFT:
689 tinput_seek_word(ti, seek_backward, true);
690 break;
691 case KC_RIGHT:
692 tinput_seek_word(ti, seek_forward, true);
693 break;
694 case KC_UP:
695 tinput_seek_vertical(ti, seek_backward, true);
696 break;
697 case KC_DOWN:
698 tinput_seek_vertical(ti, seek_forward, true);
699 break;
700 default:
701 break;
702 }
703}
704
705static void tinput_key_shift(tinput_t *ti, console_event_t *ev)
706{
707 switch (ev->key) {
708 case KC_LEFT:
709 tinput_seek_cell(ti, seek_backward, true);
710 break;
711 case KC_RIGHT:
712 tinput_seek_cell(ti, seek_forward, true);
713 break;
714 case KC_UP:
715 tinput_seek_vertical(ti, seek_backward, true);
716 break;
717 case KC_DOWN:
718 tinput_seek_vertical(ti, seek_forward, true);
719 break;
720 case KC_HOME:
721 tinput_seek_max(ti, seek_backward, true);
722 break;
723 case KC_END:
724 tinput_seek_max(ti, seek_forward, true);
725 break;
726 default:
727 break;
728 }
729}
730
731static void tinput_key_unmod(tinput_t *ti, console_event_t *ev)
732{
733 switch (ev->key) {
734 case KC_ENTER:
735 case KC_NENTER:
736 ti->done = true;
737 break;
738 case KC_BACKSPACE:
739 tinput_backspace(ti);
740 break;
741 case KC_DELETE:
742 tinput_delete(ti);
743 break;
744 case KC_LEFT:
745 tinput_seek_cell(ti, seek_backward, false);
746 break;
747 case KC_RIGHT:
748 tinput_seek_cell(ti, seek_forward, false);
749 break;
750 case KC_HOME:
751 tinput_seek_max(ti, seek_backward, false);
752 break;
753 case KC_END:
754 tinput_seek_max(ti, seek_forward, false);
755 break;
756 case KC_UP:
757 tinput_history_seek(ti, +1);
758 break;
759 case KC_DOWN:
760 tinput_history_seek(ti, -1);
761 break;
762 default:
763 break;
764 }
765}
766
[216d6fc]767void get_input(cliuser_t *usr)
768{
[19528516]769 char *str;
[216d6fc]770
[ef8bcc6]771 fflush(stdout);
[73878c1]772 console_set_style(fphone(stdout), STYLE_EMPHASIS);
[216d6fc]773 printf("%s", usr->prompt);
[ef8bcc6]774 fflush(stdout);
[73878c1]775 console_set_style(fphone(stdout), STYLE_NORMAL);
[9805cde]776
[19528516]777 str = tinput_read(&tinput);
778
779 /* Check for empty input. */
780 if (str_cmp(str, "") == 0) {
781 free(str);
[216d6fc]782 return;
[19528516]783 }
[216d6fc]784
[19528516]785 usr->line = str;
[216d6fc]786 return;
787}
[da2bd08]788
789void input_init(void)
790{
791 tinput_init(&tinput);
792}
Note: See TracBrowser for help on using the repository browser.