source: mainline/uspace/lib/vt/src/vt100.c@ b3b79981

Last change on this file since b3b79981 was b3b79981, checked in by Jiri Svoboda <jiri@…>, 10 months ago

Must initialize vt100_t decoder fields

  • Property mode set to 100644
File size: 29.1 KB
Line 
1/*
2 * Copyright (c) 2024 Jiri Svoboda
3 * Copyright (c) 2011 Martin Decky
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * - Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * - Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * - The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30/** @addtogroup libvt
31 * @{
32 */
33
34#include <ctype.h>
35#include <errno.h>
36#include <io/color.h>
37#include <io/keycode.h>
38#include <stdio.h>
39#include <stdlib.h>
40#include <vt/vt100.h>
41
42/** Map console colors to VT100 color indices */
43sgr_color_index_t color_map[] = {
44 [COLOR_BLACK] = CI_BLACK,
45 [COLOR_BLUE] = CI_BLUE,
46 [COLOR_GREEN] = CI_GREEN,
47 [COLOR_CYAN] = CI_CYAN,
48 [COLOR_RED] = CI_RED,
49 [COLOR_MAGENTA] = CI_MAGENTA,
50 [COLOR_YELLOW] = CI_BROWN,
51 [COLOR_WHITE] = CI_WHITE
52};
53
54/** Clear screen.
55 *
56 * @param vt VT instance
57 */
58void vt100_cls(vt100_t *vt)
59{
60 vt->cb->control_puts(vt->arg, "\033[2J");
61}
62
63/** ECMA-48 Set Graphics Rendition.
64 *
65 * @param vt VT instance
66 * @param mode SGR mode number
67 */
68void vt100_sgr(vt100_t *vt, unsigned int mode)
69{
70 char control[MAX_CONTROL];
71
72 snprintf(control, MAX_CONTROL, "\033[%um", mode);
73 vt->cb->control_puts(vt->arg, control);
74}
75
76/** Set Graphics Rendition with 5 arguments.
77 *
78 * @param vt VT instance
79 * @param a1 First argument
80 * @param a2 Second argument
81 * @param a3 Third argument
82 * @param a4 Fourth argument
83 * @param a5 Fifth argument
84 */
85static void vt100_sgr5(vt100_t *vt, unsigned a1, unsigned a2,
86 unsigned a3, unsigned a4, unsigned a5)
87{
88 char control[MAX_CONTROL];
89
90 snprintf(control, MAX_CONTROL, "\033[%u;%u;%u;%u;%um",
91 a1, a2, a3, a4, a5);
92 vt->cb->control_puts(vt->arg, control);
93}
94
95/** Set cussor position.
96 *
97 * @param vt VT instance
98 * @param col Column (starting from 0)
99 * @param row Row (starting from 0)
100 */
101void vt100_set_pos(vt100_t *vt, sysarg_t col, sysarg_t row)
102{
103 char control[MAX_CONTROL];
104
105 snprintf(control, MAX_CONTROL, "\033[%" PRIun ";%" PRIun "f",
106 row + 1, col + 1);
107 vt->cb->control_puts(vt->arg, control);
108}
109
110/** Set graphics rendition based on attributes,
111 *
112 * @param vt VT instance
113 * @param attrs Character attributes
114 */
115void vt100_set_sgr(vt100_t *vt, char_attrs_t attrs)
116{
117 unsigned color;
118
119 switch (attrs.type) {
120 case CHAR_ATTR_STYLE:
121 switch (attrs.val.style) {
122 case STYLE_NORMAL:
123 vt100_sgr(vt, SGR_RESET);
124 vt100_sgr(vt, SGR_BGCOLOR + CI_WHITE);
125 vt100_sgr(vt, SGR_FGCOLOR + CI_BLACK);
126 break;
127 case STYLE_EMPHASIS:
128 vt100_sgr(vt, SGR_RESET);
129 vt100_sgr(vt, SGR_BGCOLOR + CI_WHITE);
130 vt100_sgr(vt, SGR_FGCOLOR + CI_RED);
131 vt100_sgr(vt, SGR_BOLD);
132 break;
133 case STYLE_INVERTED:
134 vt100_sgr(vt, SGR_RESET);
135 vt100_sgr(vt, SGR_BGCOLOR + CI_BLACK);
136 vt100_sgr(vt, SGR_FGCOLOR + CI_WHITE);
137 break;
138 case STYLE_SELECTED:
139 vt100_sgr(vt, SGR_RESET);
140 vt100_sgr(vt, SGR_BGCOLOR + CI_RED);
141 vt100_sgr(vt, SGR_FGCOLOR + CI_WHITE);
142 break;
143 }
144 break;
145 case CHAR_ATTR_INDEX:
146 vt100_sgr(vt, SGR_RESET);
147 vt100_sgr(vt, SGR_BGCOLOR + color_map[attrs.val.index.bgcolor & 7]);
148 vt100_sgr(vt, SGR_FGCOLOR + color_map[attrs.val.index.fgcolor & 7]);
149
150 if (attrs.val.index.attr & CATTR_BRIGHT)
151 vt100_sgr(vt, SGR_BOLD);
152
153 break;
154 case CHAR_ATTR_RGB:
155 if (vt->enable_rgb == true) {
156 vt100_sgr5(vt, 48, 2, RED(attrs.val.rgb.bgcolor),
157 GREEN(attrs.val.rgb.bgcolor),
158 BLUE(attrs.val.rgb.bgcolor));
159 vt100_sgr5(vt, 38, 2, RED(attrs.val.rgb.fgcolor),
160 GREEN(attrs.val.rgb.fgcolor),
161 BLUE(attrs.val.rgb.fgcolor));
162 } else {
163 vt100_sgr(vt, SGR_RESET);
164 color =
165 ((RED(attrs.val.rgb.fgcolor) >= 0x80) ? COLOR_RED : 0) |
166 ((GREEN(attrs.val.rgb.fgcolor) >= 0x80) ? COLOR_GREEN : 0) |
167 ((BLUE(attrs.val.rgb.fgcolor) >= 0x80) ? COLOR_BLUE : 0);
168 vt100_sgr(vt, SGR_FGCOLOR + color_map[color]);
169 color =
170 ((RED(attrs.val.rgb.bgcolor) >= 0x80) ? COLOR_RED : 0) |
171 ((GREEN(attrs.val.rgb.bgcolor) >= 0x80) ? COLOR_GREEN : 0) |
172 ((BLUE(attrs.val.rgb.bgcolor) >= 0x80) ? COLOR_BLUE : 0);
173 vt100_sgr(vt, SGR_BGCOLOR + color_map[color]);
174 }
175 break;
176 }
177}
178
179/** Create VT instance.
180 *
181 * @param arg Argument passed to callback functions
182 * @param cols Number of columns
183 * @param rows Number of rows
184 * @param cb Callback functions
185 *
186 * @return Pointer to new VT instance on success, NULL on failure.
187 */
188vt100_t *vt100_create(void *arg, sysarg_t cols, sysarg_t rows, vt100_cb_t *cb)
189{
190 vt100_t *vt = malloc(sizeof(vt100_t));
191 if (vt == NULL)
192 return NULL;
193
194 vt->cb = cb;
195 vt->arg = arg;
196
197 vt->cols = cols;
198 vt->rows = rows;
199
200 vt->cur_col = (sysarg_t) -1;
201 vt->cur_row = (sysarg_t) -1;
202
203 vt->cur_attrs.type = -1;
204 vt->cur_attrs.val.style = -1;
205
206 vt->state = vts_base;
207 vt->inncnt = 0;
208
209 return vt;
210}
211
212/** Resize VT instance.
213 *
214 * @param vt VT instance
215 * @param cols New number of columns
216 * @param rows New number of rows
217 */
218void vt100_resize(vt100_t *vt, sysarg_t cols, sysarg_t rows)
219{
220 vt->cols = cols;
221 vt->rows = rows;
222
223 if (vt->cur_col > cols - 1)
224 vt->cur_col = cols - 1;
225 if (vt->cur_row > rows - 1)
226 vt->cur_row = rows - 1;
227}
228
229/** Destroy VT instance.
230 *
231 * @param vt VT instance
232 */
233void vt100_destroy(vt100_t *vt)
234{
235 free(vt);
236}
237
238/** Get VT size.
239 *
240 * @param vt VT instance
241 * @param cols Place to store number of columns
242 * @param rows Place to store number of rows
243 */
244void vt100_get_dimensions(vt100_t *vt, sysarg_t *cols,
245 sysarg_t *rows)
246{
247 *cols = vt->cols;
248 *rows = vt->rows;
249}
250
251/** Temporarily yield VT to other users.
252 *
253 * @param vt VT instance
254 * @return EOK on success or an error code
255 */
256errno_t vt100_yield(vt100_t *vt)
257{
258 return EOK;
259}
260
261/** Reclaim VT.
262 *
263 * @param vt VT instance
264 * @return EOK on success or an error code
265 */
266errno_t vt100_claim(vt100_t *vt)
267{
268 return EOK;
269}
270
271/** Go to specified position, if needed.
272 *
273 * @param vt VT instance
274 * @param col Column (starting from 0)
275 * @param row Row (starting from 0)
276 */
277void vt100_goto(vt100_t *vt, sysarg_t col, sysarg_t row)
278{
279 if ((col >= vt->cols) || (row >= vt->rows))
280 return;
281
282 if ((col != vt->cur_col) || (row != vt->cur_row)) {
283 vt100_set_pos(vt, col, row);
284 vt->cur_col = col;
285 vt->cur_row = row;
286 }
287}
288
289/** Set character attributes, if needed.
290 *
291 * @param vt VT instance
292 * @param attrs Attributes
293 */
294void vt100_set_attr(vt100_t *vt, char_attrs_t attrs)
295{
296 if (!attrs_same(vt->cur_attrs, attrs)) {
297 vt100_set_sgr(vt, attrs);
298 vt->cur_attrs = attrs;
299 }
300}
301
302/** Set cursor visibility.
303 *
304 * @param vt VT instance
305 * @param @c true to make cursor visible, @c false to make it invisible
306 */
307void vt100_cursor_visibility(vt100_t *vt, bool visible)
308{
309 if (visible)
310 vt->cb->control_puts(vt->arg, "\033[?25h");
311 else
312 vt->cb->control_puts(vt->arg, "\033[?25l");
313}
314
315/** Set mouse button press/release reporting.
316 *
317 * @param vt VT instance
318 * @param @c true to enable button press/release reporting
319 */
320void vt100_set_button_reporting(vt100_t *vt, bool enable)
321{
322 if (enable) {
323 /* Enable button tracking */
324 vt->cb->control_puts(vt->arg, "\033[?1000h");
325 /* Enable SGR encoding of mouse reports */
326 vt->cb->control_puts(vt->arg, "\033[?1006h");
327 } else {
328 /* Disable button tracking */
329 vt->cb->control_puts(vt->arg, "\033[?1000l");
330 /* Disable SGR encoding of mouse reports */
331 vt->cb->control_puts(vt->arg, "\033[?1006l");
332 }
333}
334
335/** Print Unicode character.
336 *
337 * @param vt VT instance
338 * @parma ch Unicode character
339 */
340void vt100_putuchar(vt100_t *vt, char32_t ch)
341{
342 vt->cb->putuchar(vt->arg, ch == 0 ? ' ' : ch);
343 vt->cur_col++;
344
345 if (vt->cur_col >= vt->cols) {
346 vt->cur_row += vt->cur_col / vt->cols;
347 vt->cur_col %= vt->cols;
348 }
349}
350
351/** Flush VT.
352 *
353 * @param vt VT instance
354 */
355void vt100_flush(vt100_t *vt)
356{
357 vt->cb->flush(vt->arg);
358}
359
360/** Recognize a key.
361 *
362 * Generate a key callback and reset decoder state.
363 *
364 * @param vt VT instance
365 * @param mods Key modifiers
366 * @param key Key code
367 * @param c Character
368 */
369static void vt100_key(vt100_t *vt, keymod_t mods, keycode_t key, char c)
370{
371 vt->cb->key(vt->arg, mods, key, c);
372 vt->state = vts_base;
373}
374
375/** Generate position event callback.
376 * *
377 * @param vt VT instance
378 * @param ev Position event
379 */
380static void vt100_pos_event(vt100_t *vt, pos_event_t *ev)
381{
382 vt->cb->pos_event(vt->arg, ev);
383}
384
385/** Clear number decoder state.
386 *
387 * @param vt VT instance
388 */
389static void vt100_clear_innum(vt100_t *vt)
390{
391 unsigned i;
392
393 vt->inncnt = 0;
394 for (i = 0; i < INNUM_MAX; i++)
395 vt->innum[i] = 0;
396}
397
398/** Process input character with prefix 1b.
399 *
400 * @param vt VT instance
401 * @param c Input character
402 */
403static void vt100_rcvd_1b(vt100_t *vt, char c)
404{
405 switch (c) {
406 case 0x1b:
407 vt100_key(vt, 0, KC_ESCAPE, c);
408 break;
409 case 0x60:
410 vt100_key(vt, KM_ALT, KC_BACKTICK, c);
411 break;
412
413 case 0x31:
414 vt100_key(vt, KM_ALT, KC_1, c);
415 break;
416 case 0x32:
417 vt100_key(vt, KM_ALT, KC_2, c);
418 break;
419 case 0x33:
420 vt100_key(vt, KM_ALT, KC_3, c);
421 break;
422 case 0x34:
423 vt100_key(vt, KM_ALT, KC_4, c);
424 break;
425 case 0x35:
426 vt100_key(vt, KM_ALT, KC_5, c);
427 break;
428 case 0x36:
429 vt100_key(vt, KM_ALT, KC_6, c);
430 break;
431 case 0x37:
432 vt100_key(vt, KM_ALT, KC_7, c);
433 break;
434 case 0x38:
435 vt100_key(vt, KM_ALT, KC_8, c);
436 break;
437 case 0x39:
438 vt100_key(vt, KM_ALT, KC_9, c);
439 break;
440 case 0x30:
441 vt100_key(vt, KM_ALT, KC_0, c);
442 break;
443
444 case 0x2d:
445 vt100_key(vt, KM_ALT, KC_MINUS, c);
446 break;
447 case 0x3d:
448 vt100_key(vt, KM_ALT, KC_EQUALS, c);
449 break;
450
451 case 0x71:
452 vt100_key(vt, KM_ALT, KC_Q, c);
453 break;
454 case 0x77:
455 vt100_key(vt, KM_ALT, KC_W, c);
456 break;
457 case 0x65:
458 vt100_key(vt, KM_ALT, KC_E, c);
459 break;
460 case 0x72:
461 vt100_key(vt, KM_ALT, KC_R, c);
462 break;
463 case 0x74:
464 vt100_key(vt, KM_ALT, KC_T, c);
465 break;
466 case 0x79:
467 vt100_key(vt, KM_ALT, KC_Y, c);
468 break;
469 case 0x75:
470 vt100_key(vt, KM_ALT, KC_U, c);
471 break;
472 case 0x69:
473 vt100_key(vt, KM_ALT, KC_I, c);
474 break;
475 case 0x6f:
476 vt100_key(vt, KM_ALT, KC_O, c);
477 break;
478 case 0x70:
479 vt100_key(vt, KM_ALT, KC_P, c);
480 break;
481
482 /* 0x1b, 0x5b is used by other keys/sequences */
483
484 case 0x5d:
485 vt100_key(vt, KM_ALT, KC_RBRACKET, c);
486 break;
487
488 case 0x61:
489 vt100_key(vt, KM_ALT, KC_A, c);
490 break;
491 case 0x73:
492 vt100_key(vt, KM_ALT, KC_S, c);
493 break;
494 case 0x64:
495 vt100_key(vt, KM_ALT, KC_D, c);
496 break;
497 case 0x66:
498 vt100_key(vt, KM_ALT, KC_F, c);
499 break;
500 case 0x67:
501 vt100_key(vt, KM_ALT, KC_G, c);
502 break;
503 case 0x68:
504 vt100_key(vt, KM_ALT, KC_H, c);
505 break;
506 case 0x6a:
507 vt100_key(vt, KM_ALT, KC_J, c);
508 break;
509 case 0x6b:
510 vt100_key(vt, KM_ALT, KC_K, c);
511 break;
512 case 0x6c:
513 vt100_key(vt, KM_ALT, KC_L, c);
514 break;
515
516 case 0x3b:
517 vt100_key(vt, KM_ALT, KC_SEMICOLON, c);
518 break;
519 case 0x27:
520 vt100_key(vt, KM_ALT, KC_QUOTE, c);
521 break;
522 case 0x5c:
523 vt100_key(vt, KM_ALT, KC_BACKSLASH, c);
524 break;
525
526 case 0x7a:
527 vt100_key(vt, KM_ALT, KC_Z, c);
528 break;
529 case 0x78:
530 vt100_key(vt, KM_ALT, KC_X, c);
531 break;
532 case 0x63:
533 vt100_key(vt, KM_ALT, KC_C, c);
534 break;
535 case 0x76:
536 vt100_key(vt, KM_ALT, KC_V, c);
537 break;
538 case 0x62:
539 vt100_key(vt, KM_ALT, KC_B, c);
540 break;
541 case 0x6e:
542 vt100_key(vt, KM_ALT, KC_N, c);
543 break;
544 case 0x6d:
545 vt100_key(vt, KM_ALT, KC_M, c);
546 break;
547
548 case 0x2c:
549 vt100_key(vt, KM_ALT, KC_COMMA, c);
550 break;
551 case 0x2e:
552 vt100_key(vt, KM_ALT, KC_PERIOD, c);
553 break;
554 case 0x2f:
555 vt100_key(vt, KM_ALT, KC_SLASH, c);
556 break;
557
558 case 0x4f:
559 vt->state = vts_1b4f;
560 break;
561 case 0x5b:
562 vt->state = vts_1b5b;
563 break;
564 default:
565 vt->state = vts_base;
566 break;
567 }
568}
569
570/** Process input character with prefix 1b 4f.
571 *
572 * @param vt VT instance
573 * @param c Input character
574 */
575static void vt100_rcvd_1b4f(vt100_t *vt, char c)
576{
577 switch (c) {
578 case 0x50:
579 vt100_key(vt, 0, KC_F1, 0);
580 break;
581 case 0x51:
582 vt100_key(vt, 0, KC_F2, 0);
583 break;
584 case 0x52:
585 vt100_key(vt, 0, KC_F3, 0);
586 break;
587 case 0x53:
588 vt100_key(vt, 0, KC_F4, 0);
589 break;
590 case 0x48:
591 vt100_key(vt, 0, KC_HOME, 0);
592 break;
593 case 0x46:
594 vt100_key(vt, 0, KC_END, 0);
595 break;
596 default:
597 vt->state = vts_base;
598 break;
599 }
600}
601
602/** Process input character with prefix 1b 5b.
603 *
604 * @param vt VT instance
605 * @param c Input character
606 */
607static void vt100_rcvd_1b5b(vt100_t *vt, char c)
608{
609 switch (c) {
610 case 0x31:
611 vt->state = vts_1b5b31;
612 break;
613 case 0x32:
614 vt->state = vts_1b5b32;
615 break;
616 case 0x35:
617 vt->state = vts_1b5b35;
618 break;
619 case 0x33:
620 vt->state = vts_1b5b33;
621 break;
622 case 0x36:
623 vt->state = vts_1b5b36;
624 break;
625 case 0x3c:
626 vt->state = vts_1b5b3c;
627 break;
628 case 0x41:
629 vt100_key(vt, 0, KC_UP, 0);
630 break;
631 case 0x44:
632 vt100_key(vt, 0, KC_LEFT, 0);
633 break;
634 case 0x42:
635 vt100_key(vt, 0, KC_DOWN, 0);
636 break;
637 case 0x43:
638 vt100_key(vt, 0, KC_RIGHT, 0);
639 break;
640 case 0x48:
641 vt100_key(vt, 0, KC_HOME, 0);
642 break;
643 case 0x46:
644 vt100_key(vt, 0, KC_END, 0);
645 break;
646 default:
647 vt->state = vts_base;
648 break;
649 }
650}
651
652/** Process input character with prefix 1b 5b 31.
653 *
654 * @param vt VT instance
655 * @param c Input character
656 */
657static void vt100_rcvd_1b5b31(vt100_t *vt, char c)
658{
659 switch (c) {
660 case 0x35:
661 vt->state = vts_1b5b3135;
662 break;
663 case 0x37:
664 vt->state = vts_1b5b3137;
665 break;
666 case 0x38:
667 vt->state = vts_1b5b3138;
668 break;
669 case 0x39:
670 vt->state = vts_1b5b3139;
671 break;
672 case 0x3b:
673 vt->state = vts_1b5b313b;
674 break;
675 default:
676 vt->state = vts_base;
677 break;
678 }
679}
680
681/** Process input character with prefix 1b 5b 31 35.
682 *
683 * @param vt VT instance
684 * @param c Input character
685 */
686static void vt100_rcvd_1b5b3135(vt100_t *vt, char c)
687{
688 switch (c) {
689 case 0x7e:
690 vt100_key(vt, 0, KC_F5, 0);
691 break;
692 default:
693 vt->state = vts_base;
694 break;
695 }
696}
697
698/** Process input character with prefix 1b 5b 31 37.
699 *
700 * @param vt VT instance
701 * @param c Input character
702 */
703static void vt100_rcvd_1b5b3137(vt100_t *vt, char c)
704{
705 switch (c) {
706 case 0x7e:
707 vt100_key(vt, 0, KC_F6, 0);
708 break;
709 default:
710 vt->state = vts_base;
711 break;
712 }
713}
714
715/** Process input character with prefix 1b 5b 31 38.
716 *
717 * @param vt VT instance
718 * @param c Input character
719 */
720static void vt100_rcvd_1b5b3138(vt100_t *vt, char c)
721{
722 switch (c) {
723 case 0x7e:
724 vt100_key(vt, 0, KC_F7, 0);
725 break;
726 default:
727 vt->state = vts_base;
728 break;
729 }
730}
731
732/** Process input character with prefix 1b 5b 31 39.
733 *
734 * @param vt VT instance
735 * @param c Input character
736 */
737static void vt100_rcvd_1b5b3139(vt100_t *vt, char c)
738{
739 switch (c) {
740 case 0x7e:
741 vt100_key(vt, 0, KC_F8, 0);
742 break;
743 default:
744 vt->state = vts_base;
745 break;
746 }
747}
748
749/** Process input character with prefix 1b 5b 31 3b.
750 *
751 * @param vt VT instance
752 * @param c Input character
753 */
754static void vt100_rcvd_1b5b313b(vt100_t *vt, char c)
755{
756 switch (c) {
757 case 0x32:
758 vt->state = vts_1b5b313b32;
759 break;
760 case 0x33:
761 vt->state = vts_1b5b313b33;
762 break;
763 default:
764 vt->state = vts_base;
765 break;
766 }
767}
768
769/** Process input character with prefix 1b 5b 31 3b 32.
770 *
771 * @param vt VT instance
772 * @param c Input character
773 */
774static void vt100_rcvd_1b5b313b32(vt100_t *vt, char c)
775{
776 switch (c) {
777 case 0x41:
778 vt100_key(vt, KM_SHIFT, KC_UP, 0);
779 break;
780 case 0x44:
781 vt100_key(vt, KM_SHIFT, KC_LEFT, 0);
782 break;
783 case 0x42:
784 vt100_key(vt, KM_SHIFT, KC_DOWN, 0);
785 break;
786 case 0x43:
787 vt100_key(vt, KM_SHIFT, KC_RIGHT, 0);
788 break;
789 case 0x48:
790 vt100_key(vt, KM_SHIFT, KC_HOME, 0);
791 break;
792 case 0x46:
793 vt100_key(vt, KM_SHIFT, KC_END, 0);
794 break;
795 default:
796 vt->state = vts_base;
797 break;
798 }
799}
800
801/** Process input character with prefix 1b 5b 31 3b 33.
802 *
803 * @param vt VT instance
804 * @param c Input character
805 */
806static void vt100_rcvd_1b5b313b33(vt100_t *vt, char c)
807{
808 switch (c) {
809 case 0x41:
810 vt100_key(vt, KM_ALT, KC_UP, 0);
811 break;
812 case 0x44:
813 vt100_key(vt, KM_ALT, KC_LEFT, 0);
814 break;
815 case 0x42:
816 vt100_key(vt, KM_ALT, KC_DOWN, 0);
817 break;
818 case 0x43:
819 vt100_key(vt, KM_ALT, KC_RIGHT, 0);
820 break;
821 case 0x48:
822 vt100_key(vt, KM_ALT, KC_HOME, 0);
823 break;
824 case 0x46:
825 vt100_key(vt, KM_ALT, KC_END, 0);
826 break;
827 default:
828 vt->state = vts_base;
829 break;
830 }
831}
832
833/** Process input character with prefix 1b 5b 32.
834 *
835 * @param vt VT instance
836 * @param c Input character
837 */
838static void vt100_rcvd_1b5b32(vt100_t *vt, char c)
839{
840 switch (c) {
841 case 0x30:
842 vt->state = vts_1b5b3230;
843 break;
844 case 0x31:
845 vt->state = vts_1b5b3231;
846 break;
847 case 0x33:
848 vt->state = vts_1b5b3233;
849 break;
850 case 0x34:
851 vt->state = vts_1b5b3234;
852 break;
853 case 0x35:
854 vt->state = vts_1b5b3235;
855 break;
856 case 0x38:
857 vt->state = vts_1b5b3238;
858 break;
859 case 0x7e:
860 vt100_key(vt, 0, KC_INSERT, 0);
861 break;
862 default:
863 vt->state = vts_base;
864 break;
865 }
866}
867
868/** Process input character with prefix 1b 5b 32 30.
869 *
870 * @param vt VT instance
871 * @param c Input character
872 */
873static void vt100_rcvd_1b5b3230(vt100_t *vt, char c)
874{
875 switch (c) {
876 case 0x7e:
877 vt100_key(vt, 0, KC_F9, 0);
878 break;
879 default:
880 vt->state = vts_base;
881 break;
882 }
883}
884
885/** Process input character with prefix 1b 5b 32 31.
886 *
887 * @param vt VT instance
888 * @param c Input character
889 */
890static void vt100_rcvd_1b5b3231(vt100_t *vt, char c)
891{
892 switch (c) {
893 case 0x7e:
894 vt100_key(vt, 0, KC_F10, 0);
895 break;
896 default:
897 vt->state = vts_base;
898 break;
899 }
900}
901
902/** Process input character with prefix 1b 5b 32 33.
903 *
904 * @param vt VT instance
905 * @param c Input character
906 */
907static void vt100_rcvd_1b5b3233(vt100_t *vt, char c)
908{
909 switch (c) {
910 case 0x7e:
911 vt100_key(vt, 0, KC_F11, 0);
912 break;
913 default:
914 vt->state = vts_base;
915 break;
916 }
917}
918
919/** Process input character with prefix 1b 5b 32 34.
920 *
921 * @param vt VT instance
922 * @param c Input character
923 */
924static void vt100_rcvd_1b5b3234(vt100_t *vt, char c)
925{
926 switch (c) {
927 case 0x7e:
928 vt100_key(vt, 0, KC_F12, 0);
929 break;
930 default:
931 vt->state = vts_base;
932 break;
933 }
934}
935
936/** Process input character with prefix 1b 5b 32 35.
937 *
938 * @param vt VT instance
939 * @param c Input character
940 */
941static void vt100_rcvd_1b5b3235(vt100_t *vt, char c)
942{
943 switch (c) {
944 case 0x7e:
945 vt100_key(vt, 0, KC_PRTSCR, 0);
946 break;
947 default:
948 vt->state = vts_base;
949 break;
950 }
951}
952
953/** Process input character with prefix 1b 5b 32 38.
954 *
955 * @param vt VT instance
956 * @param c Input character
957 */
958static void vt100_rcvd_1b5b3238(vt100_t *vt, char c)
959{
960 switch (c) {
961 case 0x7e:
962 vt100_key(vt, 0, KC_PAUSE, 0);
963 break;
964 default:
965 vt->state = vts_base;
966 break;
967 }
968}
969
970/** Process input character with prefix 1b 5b 35.
971 *
972 * @param vt VT instance
973 * @param c Input character
974 */
975static void vt100_rcvd_1b5b35(vt100_t *vt, char c)
976{
977 switch (c) {
978 case 0x7e:
979 vt100_key(vt, 0, KC_PAGE_UP, 0);
980 break;
981 default:
982 vt->state = vts_base;
983 break;
984 }
985}
986
987/** Process input character with prefix 1b 5b 33.
988 *
989 * @param vt VT instance
990 * @param c Input character
991 */
992static void vt100_rcvd_1b5b33(vt100_t *vt, char c)
993{
994 switch (c) {
995 case 0x7e:
996 vt100_key(vt, 0, KC_DELETE, 0);
997 break;
998 default:
999 vt->state = vts_base;
1000 break;
1001 }
1002}
1003
1004/** Process input character with prefix 1b 5b 36.
1005 *
1006 * @param vt VT instance
1007 * @param c Input character
1008 */
1009static void vt100_rcvd_1b5b36(vt100_t *vt, char c)
1010{
1011 switch (c) {
1012 case 0x7e:
1013 vt100_key(vt, 0, KC_PAGE_DOWN, 0);
1014 break;
1015 default:
1016 vt->state = vts_base;
1017 break;
1018 }
1019}
1020
1021/** Process input character with prefix 1b 5b 3c - mouse report.
1022 *
1023 * @param vt VT instance
1024 * @param c Input character
1025 */
1026static void vt100_rcvd_1b5b3c(vt100_t *vt, char c)
1027{
1028 pos_event_t ev;
1029
1030 if (isdigit(c)) {
1031 /* Decode next base-10 digit */
1032 vt->innum[vt->inncnt] = vt->innum[vt->inncnt] * 10 + (c - '0');
1033 } else if (c == ';') {
1034 /* Move to next parameter */
1035 if (vt->inncnt >= INNUM_MAX - 1) {
1036 vt->state = vts_base;
1037 vt100_clear_innum(vt);
1038 return;
1039 }
1040 ++vt->inncnt;
1041 } else {
1042 switch (c) {
1043 case 'M':
1044 case 'm':
1045 /* Button press / release */
1046 ev.pos_id = 0;
1047 ev.type = (c == 'M') ? POS_PRESS : POS_RELEASE;
1048
1049 /*
1050 * VT reports button 0 = left button,
1051 * 1 = middle, 2 = right.
1052 * pos_event needs 1 = left, 2 = right, 3 = middle,...
1053 * so right and middle need to be reversed.
1054 */
1055 switch (vt->innum[0]) {
1056 case 1:
1057 ev.btn_num = 3;
1058 break;
1059 case 2:
1060 ev.btn_num = 2;
1061 break;
1062 default:
1063 ev.btn_num = 1 + vt->innum[0];
1064 break;
1065 }
1066 ev.hpos = vt->innum[1] - 1;
1067 ev.vpos = vt->innum[2] - 1;
1068 vt100_pos_event(vt, &ev);
1069 break;
1070 }
1071 vt100_clear_innum(vt);
1072 vt->state = vts_base;
1073 }
1074}
1075
1076/** Process input character (base state, no prefix).
1077 *
1078 * @param vt VT instance
1079 * @param c Input character
1080 */
1081static void vt100_rcvd_base(vt100_t *vt, char c)
1082{
1083 switch (c) {
1084 /*
1085 * Not shifted
1086 */
1087 case 0x60:
1088 vt100_key(vt, 0, KC_BACKTICK, c);
1089 break;
1090
1091 case 0x31:
1092 vt100_key(vt, 0, KC_1, c);
1093 break;
1094 case 0x32:
1095 vt100_key(vt, 0, KC_2, c);
1096 break;
1097 case 0x33:
1098 vt100_key(vt, 0, KC_3, c);
1099 break;
1100 case 0x34:
1101 vt100_key(vt, 0, KC_4, c);
1102 break;
1103 case 0x35:
1104 vt100_key(vt, 0, KC_5, c);
1105 break;
1106 case 0x36:
1107 vt100_key(vt, 0, KC_6, c);
1108 break;
1109 case 0x37:
1110 vt100_key(vt, 0, KC_7, c);
1111 break;
1112 case 0x38:
1113 vt100_key(vt, 0, KC_8, c);
1114 break;
1115 case 0x39:
1116 vt100_key(vt, 0, KC_9, c);
1117 break;
1118 case 0x30:
1119 vt100_key(vt, 0, KC_0, c);
1120 break;
1121 case 0x2d:
1122 vt100_key(vt, 0, KC_MINUS, c);
1123 break;
1124 case 0x3d:
1125 vt100_key(vt, 0, KC_EQUALS, c);
1126 break;
1127
1128 case 0x08:
1129 vt100_key(vt, 0, KC_BACKSPACE, c);
1130 break;
1131
1132 case 0x09:
1133 vt100_key(vt, 0, KC_TAB, c);
1134 break;
1135
1136 case 0x71:
1137 vt100_key(vt, 0, KC_Q, c);
1138 break;
1139 case 0x77:
1140 vt100_key(vt, 0, KC_W, c);
1141 break;
1142 case 0x65:
1143 vt100_key(vt, 0, KC_E, c);
1144 break;
1145 case 0x72:
1146 vt100_key(vt, 0, KC_R, c);
1147 break;
1148 case 0x74:
1149 vt100_key(vt, 0, KC_T, c);
1150 break;
1151 case 0x79:
1152 vt100_key(vt, 0, KC_Y, c);
1153 break;
1154 case 0x75:
1155 vt100_key(vt, 0, KC_U, c);
1156 break;
1157 case 0x69:
1158 vt100_key(vt, 0, KC_I, c);
1159 break;
1160 case 0x6f:
1161 vt100_key(vt, 0, KC_O, c);
1162 break;
1163 case 0x70:
1164 vt100_key(vt, 0, KC_P, c);
1165 break;
1166
1167 case 0x5b:
1168 vt100_key(vt, 0, KC_LBRACKET, c);
1169 break;
1170 case 0x5d:
1171 vt100_key(vt, 0, KC_RBRACKET, c);
1172 break;
1173
1174 case 0x61:
1175 vt100_key(vt, 0, KC_A, c);
1176 break;
1177 case 0x73:
1178 vt100_key(vt, 0, KC_S, c);
1179 break;
1180 case 0x64:
1181 vt100_key(vt, 0, KC_D, c);
1182 break;
1183 case 0x66:
1184 vt100_key(vt, 0, KC_F, c);
1185 break;
1186 case 0x67:
1187 vt100_key(vt, 0, KC_G, c);
1188 break;
1189 case 0x68:
1190 vt100_key(vt, 0, KC_H, c);
1191 break;
1192 case 0x6a:
1193 vt100_key(vt, 0, KC_J, c);
1194 break;
1195 case 0x6b:
1196 vt100_key(vt, 0, KC_K, c);
1197 break;
1198 case 0x6c:
1199 vt100_key(vt, 0, KC_L, c);
1200 break;
1201
1202 case 0x3b:
1203 vt100_key(vt, 0, KC_SEMICOLON, c);
1204 break;
1205 case 0x27:
1206 vt100_key(vt, 0, KC_QUOTE, c);
1207 break;
1208 case 0x5c:
1209 vt100_key(vt, 0, KC_BACKSLASH, c);
1210 break;
1211
1212 case 0x7a:
1213 vt100_key(vt, 0, KC_Z, c);
1214 break;
1215 case 0x78:
1216 vt100_key(vt, 0, KC_X, c);
1217 break;
1218 case 0x63:
1219 vt100_key(vt, 0, KC_C, c);
1220 break;
1221 case 0x76:
1222 vt100_key(vt, 0, KC_V, c);
1223 break;
1224 case 0x62:
1225 vt100_key(vt, 0, KC_B, c);
1226 break;
1227 case 0x6e:
1228 vt100_key(vt, 0, KC_N, c);
1229 break;
1230 case 0x6d:
1231 vt100_key(vt, 0, KC_M, c);
1232 break;
1233
1234 case 0x2c:
1235 vt100_key(vt, 0, KC_COMMA, c);
1236 break;
1237 case 0x2e:
1238 vt100_key(vt, 0, KC_PERIOD, c);
1239 break;
1240 case 0x2f:
1241 vt100_key(vt, 0, KC_SLASH, c);
1242 break;
1243
1244 /*
1245 * Shifted
1246 */
1247 case 0x7e:
1248 vt100_key(vt, KM_SHIFT, KC_BACKTICK, c);
1249 break;
1250
1251 case 0x21:
1252 vt100_key(vt, KM_SHIFT, KC_1, c);
1253 break;
1254 case 0x40:
1255 vt100_key(vt, KM_SHIFT, KC_2, c);
1256 break;
1257 case 0x23:
1258 vt100_key(vt, KM_SHIFT, KC_3, c);
1259 break;
1260 case 0x24:
1261 vt100_key(vt, KM_SHIFT, KC_4, c);
1262 break;
1263 case 0x25:
1264 vt100_key(vt, KM_SHIFT, KC_5, c);
1265 break;
1266 case 0x5e:
1267 vt100_key(vt, KM_SHIFT, KC_6, c);
1268 break;
1269 case 0x26:
1270 vt100_key(vt, KM_SHIFT, KC_7, c);
1271 break;
1272 case 0x2a:
1273 vt100_key(vt, KM_SHIFT, KC_8, c);
1274 break;
1275 case 0x28:
1276 vt100_key(vt, KM_SHIFT, KC_9, c);
1277 break;
1278 case 0x29:
1279 vt100_key(vt, KM_SHIFT, KC_0, c);
1280 break;
1281 case 0x5f:
1282 vt100_key(vt, KM_SHIFT, KC_MINUS, c);
1283 break;
1284 case 0x2b:
1285 vt100_key(vt, KM_SHIFT, KC_EQUALS, c);
1286 break;
1287
1288 case 0x51:
1289 vt100_key(vt, KM_SHIFT, KC_Q, c);
1290 break;
1291 case 0x57:
1292 vt100_key(vt, KM_SHIFT, KC_W, c);
1293 break;
1294 case 0x45:
1295 vt100_key(vt, KM_SHIFT, KC_E, c);
1296 break;
1297 case 0x52:
1298 vt100_key(vt, KM_SHIFT, KC_R, c);
1299 break;
1300 case 0x54:
1301 vt100_key(vt, KM_SHIFT, KC_T, c);
1302 break;
1303 case 0x59:
1304 vt100_key(vt, KM_SHIFT, KC_Y, c);
1305 break;
1306 case 0x55:
1307 vt100_key(vt, KM_SHIFT, KC_U, c);
1308 break;
1309 case 0x49:
1310 vt100_key(vt, KM_SHIFT, KC_I, c);
1311 break;
1312 case 0x4f:
1313 vt100_key(vt, KM_SHIFT, KC_O, c);
1314 break;
1315 case 0x50:
1316 vt100_key(vt, KM_SHIFT, KC_P, c);
1317 break;
1318
1319 case 0x7b:
1320 vt100_key(vt, KM_SHIFT, KC_LBRACKET, c);
1321 break;
1322 case 0x7d:
1323 vt100_key(vt, KM_SHIFT, KC_RBRACKET, c);
1324 break;
1325
1326 case 0x41:
1327 vt100_key(vt, KM_SHIFT, KC_A, c);
1328 break;
1329 case 0x53:
1330 vt100_key(vt, KM_SHIFT, KC_S, c);
1331 break;
1332 case 0x44:
1333 vt100_key(vt, KM_SHIFT, KC_D, c);
1334 break;
1335 case 0x46:
1336 vt100_key(vt, KM_SHIFT, KC_F, c);
1337 break;
1338 case 0x47:
1339 vt100_key(vt, KM_SHIFT, KC_G, c);
1340 break;
1341 case 0x48:
1342 vt100_key(vt, KM_SHIFT, KC_H, c);
1343 break;
1344 case 0x4a:
1345 vt100_key(vt, KM_SHIFT, KC_J, c);
1346 break;
1347 case 0x4b:
1348 vt100_key(vt, KM_SHIFT, KC_K, c);
1349 break;
1350 case 0x4c:
1351 vt100_key(vt, KM_SHIFT, KC_L, c);
1352 break;
1353
1354 case 0x3a:
1355 vt100_key(vt, KM_SHIFT, KC_SEMICOLON, c);
1356 break;
1357 case 0x22:
1358 vt100_key(vt, KM_SHIFT, KC_QUOTE, c);
1359 break;
1360 case 0x7c:
1361 vt100_key(vt, KM_SHIFT, KC_BACKSLASH, c);
1362 break;
1363
1364 case 0x5a:
1365 vt100_key(vt, KM_SHIFT, KC_Z, c);
1366 break;
1367 case 0x58:
1368 vt100_key(vt, KM_SHIFT, KC_X, c);
1369 break;
1370 case 0x43:
1371 vt100_key(vt, KM_SHIFT, KC_C, c);
1372 break;
1373 case 0x56:
1374 vt100_key(vt, KM_SHIFT, KC_V, c);
1375 break;
1376 case 0x42:
1377 vt100_key(vt, KM_SHIFT, KC_B, c);
1378 break;
1379 case 0x4e:
1380 vt100_key(vt, KM_SHIFT, KC_N, c);
1381 break;
1382 case 0x4d:
1383 vt100_key(vt, KM_SHIFT, KC_M, c);
1384 break;
1385
1386 case 0x3c:
1387 vt100_key(vt, KM_SHIFT, KC_COMMA, c);
1388 break;
1389 case 0x3e:
1390 vt100_key(vt, KM_SHIFT, KC_PERIOD, c);
1391 break;
1392 case 0x3f:
1393 vt100_key(vt, KM_SHIFT, KC_SLASH, c);
1394 break;
1395
1396 /*
1397 * ...
1398 */
1399 case 0x20:
1400 vt100_key(vt, 0, KC_SPACE, c);
1401 break;
1402 case 0x0a:
1403 vt100_key(vt, 0, KC_ENTER, '\n');
1404 break;
1405 case 0x0d:
1406 vt100_key(vt, 0, KC_ENTER, '\n');
1407 break;
1408
1409 /*
1410 * Ctrl + key
1411 */
1412 case 0x11:
1413 vt100_key(vt, KM_CTRL, KC_Q, c);
1414 break;
1415 case 0x17:
1416 vt100_key(vt, KM_CTRL, KC_W, c);
1417 break;
1418 case 0x05:
1419 vt100_key(vt, KM_CTRL, KC_E, c);
1420 break;
1421 case 0x12:
1422 vt100_key(vt, KM_CTRL, KC_R, c);
1423 break;
1424 case 0x14:
1425 vt100_key(vt, KM_CTRL, KC_T, c);
1426 break;
1427 case 0x19:
1428 vt100_key(vt, KM_CTRL, KC_Y, c);
1429 break;
1430 case 0x15:
1431 vt100_key(vt, KM_CTRL, KC_U, c);
1432 break;
1433 case 0x0f:
1434 vt100_key(vt, KM_CTRL, KC_O, c);
1435 break;
1436 case 0x10:
1437 vt100_key(vt, KM_CTRL, KC_P, c);
1438 break;
1439
1440 case 0x01:
1441 vt100_key(vt, KM_CTRL, KC_A, c);
1442 break;
1443 case 0x13:
1444 vt100_key(vt, KM_CTRL, KC_S, c);
1445 break;
1446 case 0x04:
1447 vt100_key(vt, KM_CTRL, KC_D, c);
1448 break;
1449 case 0x06:
1450 vt100_key(vt, KM_CTRL, KC_F, c);
1451 break;
1452 case 0x07:
1453 vt100_key(vt, KM_CTRL, KC_G, c);
1454 break;
1455 case 0x0b:
1456 vt100_key(vt, KM_CTRL, KC_K, c);
1457 break;
1458 case 0x0c:
1459 vt100_key(vt, KM_CTRL, KC_L, c);
1460 break;
1461
1462 case 0x1a:
1463 vt100_key(vt, KM_CTRL, KC_Z, c);
1464 break;
1465 case 0x18:
1466 vt100_key(vt, KM_CTRL, KC_X, c);
1467 break;
1468 case 0x03:
1469 vt100_key(vt, KM_CTRL, KC_C, c);
1470 break;
1471 case 0x16:
1472 vt100_key(vt, KM_CTRL, KC_V, c);
1473 break;
1474 case 0x02:
1475 vt100_key(vt, KM_CTRL, KC_B, c);
1476 break;
1477 case 0x0e:
1478 vt100_key(vt, KM_CTRL, KC_N, c);
1479 break;
1480
1481 case 0x7f:
1482 vt100_key(vt, 0, KC_BACKSPACE, '\b');
1483 break;
1484
1485 case 0x1b:
1486 vt->state = vts_1b;
1487 break;
1488 }
1489}
1490
1491void vt100_rcvd_char(vt100_t *vt, char c)
1492{
1493 switch (vt->state) {
1494 case vts_base:
1495 vt100_rcvd_base(vt, c);
1496 break;
1497 case vts_1b:
1498 vt100_rcvd_1b(vt, c);
1499 break;
1500 case vts_1b4f:
1501 vt100_rcvd_1b4f(vt, c);
1502 break;
1503 case vts_1b5b:
1504 vt100_rcvd_1b5b(vt, c);
1505 break;
1506 case vts_1b5b31:
1507 vt100_rcvd_1b5b31(vt, c);
1508 break;
1509 case vts_1b5b3135:
1510 vt100_rcvd_1b5b3135(vt, c);
1511 break;
1512 case vts_1b5b3137:
1513 vt100_rcvd_1b5b3137(vt, c);
1514 break;
1515 case vts_1b5b3138:
1516 vt100_rcvd_1b5b3138(vt, c);
1517 break;
1518 case vts_1b5b3139:
1519 vt100_rcvd_1b5b3139(vt, c);
1520 break;
1521 case vts_1b5b313b:
1522 vt100_rcvd_1b5b313b(vt, c);
1523 break;
1524 case vts_1b5b313b32:
1525 vt100_rcvd_1b5b313b32(vt, c);
1526 break;
1527 case vts_1b5b313b33:
1528 vt100_rcvd_1b5b313b33(vt, c);
1529 break;
1530 case vts_1b5b32:
1531 vt100_rcvd_1b5b32(vt, c);
1532 break;
1533 case vts_1b5b3230:
1534 vt100_rcvd_1b5b3230(vt, c);
1535 break;
1536 case vts_1b5b3231:
1537 vt100_rcvd_1b5b3231(vt, c);
1538 break;
1539 case vts_1b5b3233:
1540 vt100_rcvd_1b5b3233(vt, c);
1541 break;
1542 case vts_1b5b3234:
1543 vt100_rcvd_1b5b3234(vt, c);
1544 break;
1545 case vts_1b5b3235:
1546 vt100_rcvd_1b5b3235(vt, c);
1547 break;
1548 case vts_1b5b3238:
1549 vt100_rcvd_1b5b3238(vt, c);
1550 break;
1551 case vts_1b5b35:
1552 vt100_rcvd_1b5b35(vt, c);
1553 break;
1554 case vts_1b5b33:
1555 vt100_rcvd_1b5b33(vt, c);
1556 break;
1557 case vts_1b5b36:
1558 vt100_rcvd_1b5b36(vt, c);
1559 break;
1560 case vts_1b5b3c:
1561 vt100_rcvd_1b5b3c(vt, c);
1562 break;
1563 }
1564}
1565
1566/** @}
1567 */
Note: See TracBrowser for help on using the repository browser.