source: mainline/uspace/lib/clui/tinput.c@ 2f4438f5

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 2f4438f5 was 96b02eb9, checked in by Martin Decky <martin@…>, 15 years ago

more unification of basic types

  • use sysarg_t and native_t (unsigned and signed variant) in both kernel and uspace
  • remove ipcarg_t in favour of sysarg_t

(no change in functionality)

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