+
+
+/************************************************************************************************/
+/* TODO:
+ *
+ */
+
+#define ESC 0x1b
+
+#define KEY_TAB '\t' // TAB key
+#define KEY_CR '\r' // RETURN key
+#define KEY_BACKSPACE '\b' // Backspace key
+#define KEY_ESCAPE 0x1B // ESCAPE (pressed twice)
+
+#define KEY_DOWN 0x80 // Down arrow key
+#define KEY_UP 0x81 // Up arrow key
+#define KEY_LEFT 0x82 // Left arrow key
+#define KEY_RIGHT 0x83 // Right arrow key
+#define KEY_HOME 0x84 // Home key
+#define KEY_DC 0x85 // Delete character key
+#define KEY_IC 0x86 // Ins char/toggle ins mode key
+#define KEY_NPAGE 0x87 // Next-page key
+#define KEY_PPAGE 0x88 // Previous-page key
+#define KEY_END 0x89 // End key
+#define KEY_BTAB 0x8A // Back tab key
+#define KEY_F1 0x8B // Function key F1
+#define KEY_F(n) (KEY_F1+(n)-1) // Space for additional 12 function keys
+
+
+struct fkey_tbl_s {
+ const FLASH char *sequence; /* ESC Sequence */
+ int code; /* Keycode */
+};
+
+//typedef const FLASH struct fkey_tbl_s fkey_tbl_t;
+
+#define FKEY_TBL_ITEM(_seq, _code) { FSTR(#_seq), _code }
+
+
+
+static const FLASH struct fkey_tbl_s fkey_table[] = {
+
+FKEY_TBL_ITEM(B, KEY_DOWN), // Down arrow key
+FKEY_TBL_ITEM(A, KEY_UP), // Up arrow key
+FKEY_TBL_ITEM(D, KEY_LEFT), // Left arrow key
+FKEY_TBL_ITEM(C, KEY_RIGHT), // Right arrow key
+FKEY_TBL_ITEM(1~, KEY_HOME), // Home key
+FKEY_TBL_ITEM(3~, KEY_DC), // Delete character key
+FKEY_TBL_ITEM(2~, KEY_IC), // Ins char/toggle ins mode key
+FKEY_TBL_ITEM(6~, KEY_NPAGE), // Next-page key
+FKEY_TBL_ITEM(5~, KEY_PPAGE), // Previous-page key
+FKEY_TBL_ITEM(4~, KEY_END), // End key
+FKEY_TBL_ITEM(Z, KEY_BTAB), // Back tab key
+/* VT400: */
+FKEY_TBL_ITEM(11~, KEY_F(1)), // Function key F1
+FKEY_TBL_ITEM(12~, KEY_F(2)), // Function key F2
+FKEY_TBL_ITEM(13~, KEY_F(3)), // Function key F3
+FKEY_TBL_ITEM(14~, KEY_F(4)), // Function key F4
+FKEY_TBL_ITEM(15~, KEY_F(5)), // Function key F5
+/* Linux consoe */
+FKEY_TBL_ITEM([A, KEY_F(1)), // Function key F1
+FKEY_TBL_ITEM([B, KEY_F(2)), // Function key F2
+FKEY_TBL_ITEM([C, KEY_F(3)), // Function key F3
+FKEY_TBL_ITEM([D, KEY_F(4)), // Function key F4
+FKEY_TBL_ITEM([E, KEY_F(5)), // Function key F5
+
+FKEY_TBL_ITEM(17~, KEY_F(6)), // Function key F6
+FKEY_TBL_ITEM(18~, KEY_F(7)), // Function key F7
+FKEY_TBL_ITEM(19~, KEY_F(8)), // Function key F8
+FKEY_TBL_ITEM(20~, KEY_F(9)), // Function key F9
+FKEY_TBL_ITEM(21~, KEY_F(10)), // Function key F10
+FKEY_TBL_ITEM(23~, KEY_F(11)), // Function key F11
+FKEY_TBL_ITEM(24~, KEY_F(12)), // Function key F12
+{ NULL } /* Mark end of table */
+};
+
+
+
+typedef enum {
+ STATE_GROUND,
+ STATE_ESCAPE,
+ STATE_CSI_ENTRY
+} vtparse_state_t;
+
+#define CHB_SIZE 15
+
+static
+int vt_parse (void)
+{
+ static vtparse_state_t state = STATE_GROUND;
+ char buf[CHB_SIZE+1];
+ uint8_t param[2];
+ uint8_t i_buf;
+ uint8_t i_param;
+ int ch;
+
+
+ while (1) {
+ ch = my_getchar(1);
+// debug_getch(state, ch);
+
+ switch (state) {
+ case STATE_GROUND:
+ if (ch == ESC) {
+ state = STATE_ESCAPE;
+ continue;
+ }
+ if (ch == 0x7F) // BACKSPACE on VT200 sends DEL char
+ ch = KEY_BACKSPACE; // map it to '\b'
+ break;
+ case STATE_ESCAPE:
+ if (ch < 0)
+ continue;
+
+ if (ch == '[') {
+ state = STATE_CSI_ENTRY;
+ param[0] = param[1] = 0;
+ i_buf = 0;
+ i_param = 0;
+ continue;
+ }
+ state = STATE_GROUND;
+ break;
+ case STATE_CSI_ENTRY:
+ if (ch < 0)
+ continue;
+
+ buf[i_buf] = ch;
+ if (i_buf < CHB_SIZE)
+ i_buf++;
+ if (ch == ';') {
+ i_param++;
+ continue;
+ }
+ if (isdigit(ch)) {
+ if (i_param < 2)
+ param[i_param] = param[i_param] * 10 + ch - '0';
+ continue;
+ }
+ if (ch >= '@' && ch <= '~' && ch != '[') {
+ buf[i_buf] = '\0';
+ int_fast8_t i = 0;
+ while (fkey_table[i].sequence) {
+ if (! strcmp_P (buf, fkey_table[i].sequence)) {
+ ch = fkey_table[i].code;
+ break;
+ }
+ i++;
+ }
+ if (fkey_table[i].sequence == NULL) {
+ ch = '$'; /* KEY_ESCAPE; */
+ }
+ }
+ state = STATE_GROUND;
+ break;
+ }
+ break; /* while */
+ }
+
+ return ch;
+}
+
+/************************************************************************************************/
+
+