Changeset 6907f26 in mainline


Ignore:
Timestamp:
2024-10-03T15:42:59Z (8 days ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
master
Children:
d05c237
Parents:
d31c3ea
git-author:
Jiri Svoboda <jiri@…> (2024-10-02 17:42:46)
git-committer:
Jiri Svoboda <jiri@…> (2024-10-03 15:42:59)
Message:

Parse VT100 keyboard escape sequences in libvt

Location:
uspace
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/vt/include/vt/vt100.h

    rd31c3ea r6907f26  
    3636
    3737#include <io/charfield.h>
     38#include <io/keycode.h>
    3839#include <ipc/common.h>
    3940#include <uchar.h>
     
    7576        void (*control_puts)(void *, const char *);
    7677        void (*flush)(void *);
     78        void (*key)(void *, keymod_t, keycode_t, char);
    7779} vt100_cb_t;
     80
     81/** VT100 decoding state */
     82typedef enum {
     83        /** Base state */
     84        vts_base,
     85        /** Prefix 1b */
     86        vts_1b,
     87        /** Prefix 1b 4f */
     88        vts_1b4f,
     89        /** Prefix 1b 5b */
     90        vts_1b5b,
     91        /** Prefix 1b 5b 31 */
     92        vts_1b5b31,
     93        /** Prefix 1b 5b 31 35 */
     94        vts_1b5b3135,
     95        /** Prefix 1b 5b 31 37 */
     96        vts_1b5b3137,
     97        /** Prefix 1b 5b 31 38 */
     98        vts_1b5b3138,
     99        /** Prefix 1b 5b 31 39 */
     100        vts_1b5b3139,
     101        /** Prefix 1b 5b 32 */
     102        vts_1b5b32,
     103        /** Prefix 1b 5b 32 30 */
     104        vts_1b5b3230,
     105        /** Prefix 1b 5b 32 31 */
     106        vts_1b5b3231,
     107        /** Prefix 1b 5b 32 33 */
     108        vts_1b5b3233,
     109        /** Prefix 1b 5b 32 34 */
     110        vts_1b5b3234,
     111        /** Prefix 1b 5b 32 35 */
     112        vts_1b5b3235,
     113        /** Prefix 1b 5b 32 38 */
     114        vts_1b5b3238,
     115        /** Prefix 1b 5b 35 */
     116        vts_1b5b35,
     117        /** Prefix 1b 5b 33 */
     118        vts_1b5b33,
     119        /** Prefix 1b 5b 36 */
     120        vts_1b5b36
     121} vt100_state_t;
    78122
    79123/** VT100 instance */
     
    98142        /** Argument to callback functions */
    99143        void *arg;
     144
     145        /** Input decoding state */
     146        vt100_state_t state;
    100147} vt100_t;
    101148
     
    119166extern void vt100_flush(vt100_t *);
    120167
     168extern void vt100_rcvd_char(vt100_t *, char);
     169
    121170#endif
    122171
  • uspace/lib/vt/meson.build

    rd31c3ea r6907f26  
    2727#
    2828
    29 deps = [ 'output' ]
     29deps = [ 'input', 'output' ]
    3030src = files(
    3131        'src/vt100.c'
  • uspace/lib/vt/src/vt100.c

    rd31c3ea r6907f26  
    3434#include <errno.h>
    3535#include <io/color.h>
     36#include <io/keycode.h>
    3637#include <stdio.h>
    3738#include <stdlib.h>
    3839#include <vt/vt100.h>
    3940
     41/** Map console colors to VT100 color indices */
    4042sgr_color_index_t color_map[] = {
    4143        [COLOR_BLACK]   = CI_BLACK,
     
    4951};
    5052
    51 void vt100_cls(vt100_t *state)
    52 {
    53         state->cb->control_puts(state->arg, "\033[2J");
    54 }
    55 
    56 /** ECMA-48 Set Graphics Rendition. */
    57 static void vt100_sgr(vt100_t *state, unsigned int mode)
     53/** Clear screen.
     54 *
     55 * @param vt VT instance
     56 */
     57void vt100_cls(vt100_t *vt)
     58{
     59        vt->cb->control_puts(vt->arg, "\033[2J");
     60}
     61
     62/** ECMA-48 Set Graphics Rendition.
     63 *
     64 * @param vt VT instance
     65 * @param mode SGR mode number
     66 */
     67static void vt100_sgr(vt100_t *vt, unsigned int mode)
    5868{
    5969        char control[MAX_CONTROL];
    6070
    6171        snprintf(control, MAX_CONTROL, "\033[%um", mode);
    62         state->cb->control_puts(state->arg, control);
    63 }
    64 
    65 /** Set Graphics Rendition with 5 arguments. */
    66 static void vt100_sgr5(vt100_t *state, unsigned a1, unsigned a2,
     72        vt->cb->control_puts(vt->arg, control);
     73}
     74
     75/** Set Graphics Rendition with 5 arguments.
     76 *
     77 * @param vt VT instance
     78 * @param a1 First argument
     79 * @param a2 Second argument
     80 * @param a3 Third argument
     81 * @param a4 Fourth argument
     82 * @param a5 Fifth argument
     83 */
     84static void vt100_sgr5(vt100_t *vt, unsigned a1, unsigned a2,
    6785    unsigned a3, unsigned a4, unsigned a5)
    6886{
     
    7189        snprintf(control, MAX_CONTROL, "\033[%u;%u;%u;%u;%um",
    7290            a1, a2, a3, a4, a5);
    73         state->cb->control_puts(state->arg, control);
    74 }
    75 
    76 void vt100_set_pos(vt100_t *state, sysarg_t col, sysarg_t row)
     91        vt->cb->control_puts(vt->arg, control);
     92}
     93
     94/** Set cussor position.
     95 *
     96 * @param vt VT instance
     97 * @param col Column (starting from 0)
     98 * @param row Row (starting from 0)
     99 */
     100void vt100_set_pos(vt100_t *vt, sysarg_t col, sysarg_t row)
    77101{
    78102        char control[MAX_CONTROL];
     
    80104        snprintf(control, MAX_CONTROL, "\033[%" PRIun ";%" PRIun "f",
    81105            row + 1, col + 1);
    82         state->cb->control_puts(state->arg, control);
    83 }
    84 
    85 void vt100_set_sgr(vt100_t *state, char_attrs_t attrs)
     106        vt->cb->control_puts(vt->arg, control);
     107}
     108
     109/** Set graphics rendition based on attributes,
     110 *
     111 * @param vt VT instance
     112 * @param attrs Character attributes
     113 */
     114void vt100_set_sgr(vt100_t *vt, char_attrs_t attrs)
    86115{
    87116        unsigned color;
     
    91120                switch (attrs.val.style) {
    92121                case STYLE_NORMAL:
    93                         vt100_sgr(state, SGR_RESET);
    94                         vt100_sgr(state, SGR_BGCOLOR + CI_WHITE);
    95                         vt100_sgr(state, SGR_FGCOLOR + CI_BLACK);
     122                        vt100_sgr(vt, SGR_RESET);
     123                        vt100_sgr(vt, SGR_BGCOLOR + CI_WHITE);
     124                        vt100_sgr(vt, SGR_FGCOLOR + CI_BLACK);
    96125                        break;
    97126                case STYLE_EMPHASIS:
    98                         vt100_sgr(state, SGR_RESET);
    99                         vt100_sgr(state, SGR_BGCOLOR + CI_WHITE);
    100                         vt100_sgr(state, SGR_FGCOLOR + CI_RED);
    101                         vt100_sgr(state, SGR_BOLD);
     127                        vt100_sgr(vt, SGR_RESET);
     128                        vt100_sgr(vt, SGR_BGCOLOR + CI_WHITE);
     129                        vt100_sgr(vt, SGR_FGCOLOR + CI_RED);
     130                        vt100_sgr(vt, SGR_BOLD);
    102131                        break;
    103132                case STYLE_INVERTED:
    104                         vt100_sgr(state, SGR_RESET);
    105                         vt100_sgr(state, SGR_BGCOLOR + CI_BLACK);
    106                         vt100_sgr(state, SGR_FGCOLOR + CI_WHITE);
     133                        vt100_sgr(vt, SGR_RESET);
     134                        vt100_sgr(vt, SGR_BGCOLOR + CI_BLACK);
     135                        vt100_sgr(vt, SGR_FGCOLOR + CI_WHITE);
    107136                        break;
    108137                case STYLE_SELECTED:
    109                         vt100_sgr(state, SGR_RESET);
    110                         vt100_sgr(state, SGR_BGCOLOR + CI_RED);
    111                         vt100_sgr(state, SGR_FGCOLOR + CI_WHITE);
     138                        vt100_sgr(vt, SGR_RESET);
     139                        vt100_sgr(vt, SGR_BGCOLOR + CI_RED);
     140                        vt100_sgr(vt, SGR_FGCOLOR + CI_WHITE);
    112141                        break;
    113142                }
    114143                break;
    115144        case CHAR_ATTR_INDEX:
    116                 vt100_sgr(state, SGR_RESET);
    117                 vt100_sgr(state, SGR_BGCOLOR + color_map[attrs.val.index.bgcolor & 7]);
    118                 vt100_sgr(state, SGR_FGCOLOR + color_map[attrs.val.index.fgcolor & 7]);
     145                vt100_sgr(vt, SGR_RESET);
     146                vt100_sgr(vt, SGR_BGCOLOR + color_map[attrs.val.index.bgcolor & 7]);
     147                vt100_sgr(vt, SGR_FGCOLOR + color_map[attrs.val.index.fgcolor & 7]);
    119148
    120149                if (attrs.val.index.attr & CATTR_BRIGHT)
    121                         vt100_sgr(state, SGR_BOLD);
     150                        vt100_sgr(vt, SGR_BOLD);
    122151
    123152                break;
    124153        case CHAR_ATTR_RGB:
    125                 if (state->enable_rgb == true) {
    126                         vt100_sgr5(state, 48, 2, RED(attrs.val.rgb.bgcolor),
     154                if (vt->enable_rgb == true) {
     155                        vt100_sgr5(vt, 48, 2, RED(attrs.val.rgb.bgcolor),
    127156                            GREEN(attrs.val.rgb.bgcolor),
    128157                            BLUE(attrs.val.rgb.bgcolor));
    129                         vt100_sgr5(state, 38, 2, RED(attrs.val.rgb.fgcolor),
     158                        vt100_sgr5(vt, 38, 2, RED(attrs.val.rgb.fgcolor),
    130159                            GREEN(attrs.val.rgb.fgcolor),
    131160                            BLUE(attrs.val.rgb.fgcolor));
    132161                } else {
    133                         vt100_sgr(state, SGR_RESET);
     162                        vt100_sgr(vt, SGR_RESET);
    134163                        color =
    135164                            ((RED(attrs.val.rgb.fgcolor) >= 0x80) ? COLOR_RED : 0) |
    136165                            ((GREEN(attrs.val.rgb.fgcolor) >= 0x80) ? COLOR_GREEN : 0) |
    137166                            ((BLUE(attrs.val.rgb.fgcolor) >= 0x80) ? COLOR_BLUE : 0);
    138                         vt100_sgr(state, SGR_FGCOLOR + color_map[color]);
     167                        vt100_sgr(vt, SGR_FGCOLOR + color_map[color]);
    139168                        color =
    140169                            ((RED(attrs.val.rgb.bgcolor) >= 0x80) ? COLOR_RED : 0) |
    141170                            ((GREEN(attrs.val.rgb.bgcolor) >= 0x80) ? COLOR_GREEN : 0) |
    142171                            ((BLUE(attrs.val.rgb.bgcolor) >= 0x80) ? COLOR_BLUE : 0);
    143                         vt100_sgr(state, SGR_BGCOLOR + color_map[color]);
     172                        vt100_sgr(vt, SGR_BGCOLOR + color_map[color]);
    144173                }
    145174                break;
     
    147176}
    148177
     178/** Create VT instance.
     179 *
     180 * @param arg Argument passed to callback functions
     181 * @param cols Number of columns
     182 * @param rows Number of rows
     183 * @param cb Callback functions
     184 *
     185 * @return Pointer to new VT instance on success, NULL on failure.
     186 */
    149187vt100_t *vt100_create(void *arg, sysarg_t cols, sysarg_t rows, vt100_cb_t *cb)
    150188{
    151         vt100_t *state = malloc(sizeof(vt100_t));
    152         if (state == NULL)
     189        vt100_t *vt = malloc(sizeof(vt100_t));
     190        if (vt == NULL)
    153191                return NULL;
    154192
    155         state->cb = cb;
    156         state->arg = arg;
    157 
    158         state->cols = cols;
    159         state->rows = rows;
    160 
    161         state->cur_col = (sysarg_t) -1;
    162         state->cur_row = (sysarg_t) -1;
    163 
    164         state->cur_attrs.type = CHAR_ATTR_STYLE;
    165         state->cur_attrs.val.style = STYLE_NORMAL;
    166 
    167         return state;
    168 }
    169 
    170 void vt100_destroy(vt100_t *state)
    171 {
    172         free(state);
    173 }
    174 
    175 void vt100_get_dimensions(vt100_t *state, sysarg_t *cols,
     193        vt->cb = cb;
     194        vt->arg = arg;
     195
     196        vt->cols = cols;
     197        vt->rows = rows;
     198
     199        vt->cur_col = (sysarg_t) -1;
     200        vt->cur_row = (sysarg_t) -1;
     201
     202        vt->cur_attrs.type = CHAR_ATTR_STYLE;
     203        vt->cur_attrs.val.style = STYLE_NORMAL;
     204
     205        return vt;
     206}
     207
     208/** Destroy VT instance.
     209 *
     210 * @param vt VT instance
     211 */
     212void vt100_destroy(vt100_t *vt)
     213{
     214        free(vt);
     215}
     216
     217/** Get VT size.
     218 *
     219 * @param vt VT instance
     220 * @param cols Place to store number of columns
     221 * @param rows Place to store number of rows
     222 */
     223void vt100_get_dimensions(vt100_t *vt, sysarg_t *cols,
    176224    sysarg_t *rows)
    177225{
    178         *cols = state->cols;
    179         *rows = state->rows;
    180 }
    181 
    182 errno_t vt100_yield(vt100_t *state)
     226        *cols = vt->cols;
     227        *rows = vt->rows;
     228}
     229
     230/** Temporarily yield VT to other users.
     231 *
     232 * @param vt VT instance
     233 * @return EOK on success or an error code
     234 */
     235errno_t vt100_yield(vt100_t *vt)
    183236{
    184237        return EOK;
    185238}
    186239
    187 errno_t vt100_claim(vt100_t *state)
     240/** Reclaim VT.
     241 *
     242 * @param vt VT instance
     243 * @return EOK on success or an error code
     244 */
     245errno_t vt100_claim(vt100_t *vt)
    188246{
    189247        return EOK;
    190248}
    191249
    192 void vt100_goto(vt100_t *state, sysarg_t col, sysarg_t row)
    193 {
    194         if ((col >= state->cols) || (row >= state->rows))
     250/** Go to specified position, if needed.
     251 *
     252 * @param vt VT instance
     253 * @param col Column (starting from 0)
     254 * @param row Row (starting from 0)
     255 */
     256void vt100_goto(vt100_t *vt, sysarg_t col, sysarg_t row)
     257{
     258        if ((col >= vt->cols) || (row >= vt->rows))
    195259                return;
    196260
    197         if ((col != state->cur_col) || (row != state->cur_row)) {
    198                 vt100_set_pos(state, col, row);
    199                 state->cur_col = col;
    200                 state->cur_row = row;
    201         }
    202 }
    203 
    204 void vt100_set_attr(vt100_t *state, char_attrs_t attrs)
    205 {
    206         if (!attrs_same(state->cur_attrs, attrs)) {
    207                 vt100_set_sgr(state, attrs);
    208                 state->cur_attrs = attrs;
    209         }
    210 }
    211 
    212 void vt100_cursor_visibility(vt100_t *state, bool visible)
     261        if ((col != vt->cur_col) || (row != vt->cur_row)) {
     262                vt100_set_pos(vt, col, row);
     263                vt->cur_col = col;
     264                vt->cur_row = row;
     265        }
     266}
     267
     268/** Set character attributes, if needed.
     269 *
     270 * @param vt VT instance
     271 * @param attrs Attributes
     272 */
     273void vt100_set_attr(vt100_t *vt, char_attrs_t attrs)
     274{
     275        if (!attrs_same(vt->cur_attrs, attrs)) {
     276                vt100_set_sgr(vt, attrs);
     277                vt->cur_attrs = attrs;
     278        }
     279}
     280
     281/** Set cursor visibility.
     282 *
     283 * @param vt VT instance
     284 * @param @c true to make cursor visible, @c false to make it invisible
     285 */
     286void vt100_cursor_visibility(vt100_t *vt, bool visible)
    213287{
    214288        if (visible)
    215                 state->cb->control_puts(state->arg, "\033[?25h");
     289                vt->cb->control_puts(vt->arg, "\033[?25h");
    216290        else
    217                 state->cb->control_puts(state->arg, "\033[?25l");
    218 }
    219 
    220 void vt100_putuchar(vt100_t *state, char32_t ch)
    221 {
    222         state->cb->putuchar(state->arg, ch == 0 ? ' ' : ch);
    223         state->cur_col++;
    224 
    225         if (state->cur_col >= state->cols) {
    226                 state->cur_row += state->cur_col / state->cols;
    227                 state->cur_col %= state->cols;
    228         }
    229 }
    230 
    231 void vt100_flush(vt100_t *state)
    232 {
    233         state->cb->flush(state->arg);
     291                vt->cb->control_puts(vt->arg, "\033[?25l");
     292}
     293
     294/** Print Unicode character.
     295 *
     296 * @param vt VT instance
     297 * @parma ch Unicode character
     298 */
     299void vt100_putuchar(vt100_t *vt, char32_t ch)
     300{
     301        vt->cb->putuchar(vt->arg, ch == 0 ? ' ' : ch);
     302        vt->cur_col++;
     303
     304        if (vt->cur_col >= vt->cols) {
     305                vt->cur_row += vt->cur_col / vt->cols;
     306                vt->cur_col %= vt->cols;
     307        }
     308}
     309
     310/** Flush VT.
     311 *
     312 * @param vt VT instance
     313 */
     314void vt100_flush(vt100_t *vt)
     315{
     316        vt->cb->flush(vt->arg);
     317}
     318
     319/** Recognize a key.
     320 *
     321 * Generate a key callback and reset decoder state.
     322 *
     323 * @param vt VT instance
     324 * @param mods Key modifiers
     325 * @param key Key code
     326 * @param c Character
     327 */
     328static void vt100_key(vt100_t *vt, keymod_t mods, keycode_t key, char c)
     329{
     330        vt->cb->key(vt->arg, mods, key, c);
     331        vt->state = vts_base;
     332}
     333
     334/** Process input character with prefix 1b.
     335 *
     336 * @param vt VT instance
     337 * @param c Input character
     338 */
     339static void vt100_rcvd_1b(vt100_t *vt, char c)
     340{
     341        switch (c) {
     342        case 0x1b:
     343                vt100_key(vt, 0, KC_ESCAPE, c);
     344                break;
     345        case 0x60:
     346                vt100_key(vt, KM_ALT, KC_BACKTICK, 0);
     347                break;
     348
     349        case 0x31:
     350                vt100_key(vt, KM_ALT, KC_1, 0);
     351                break;
     352        case 0x32:
     353                vt100_key(vt, KM_ALT, KC_2, 0);
     354                break;
     355        case 0x33:
     356                vt100_key(vt, KM_ALT, KC_3, 0);
     357                break;
     358        case 0x34:
     359                vt100_key(vt, KM_ALT, KC_4, 0);
     360                break;
     361        case 0x35:
     362                vt100_key(vt, KM_ALT, KC_5, 0);
     363                break;
     364        case 0x36:
     365                vt100_key(vt, KM_ALT, KC_6, 0);
     366                break;
     367        case 0x37:
     368                vt100_key(vt, KM_ALT, KC_7, 0);
     369                break;
     370        case 0x38:
     371                vt100_key(vt, KM_ALT, KC_8, 0);
     372                break;
     373        case 0x39:
     374                vt100_key(vt, KM_ALT, KC_9, 0);
     375                break;
     376        case 0x30:
     377                vt100_key(vt, KM_ALT, KC_0, 0);
     378                break;
     379
     380        case 0x2d:
     381                vt100_key(vt, KM_ALT, KC_MINUS, 0);
     382                break;
     383        case 0x3d:
     384                vt100_key(vt, KM_ALT, KC_EQUALS, 0);
     385                break;
     386
     387        case 0x71:
     388                vt100_key(vt, KM_ALT, KC_Q, 0);
     389                break;
     390        case 0x77:
     391                vt100_key(vt, KM_ALT, KC_W, 0);
     392                break;
     393        case 0x65:
     394                vt100_key(vt, KM_ALT, KC_E, 0);
     395                break;
     396        case 0x72:
     397                vt100_key(vt, KM_ALT, KC_R, 0);
     398                break;
     399        case 0x74:
     400                vt100_key(vt, KM_ALT, KC_T, 0);
     401                break;
     402        case 0x79:
     403                vt100_key(vt, KM_ALT, KC_Y, 0);
     404                break;
     405        case 0x75:
     406                vt100_key(vt, KM_ALT, KC_U, 0);
     407                break;
     408        case 0x69:
     409                vt100_key(vt, KM_ALT, KC_I, 0);
     410                break;
     411        case 0x6f:
     412                vt100_key(vt, KM_ALT, KC_O, 0);
     413                break;
     414        case 0x70:
     415                vt100_key(vt, KM_ALT, KC_P, 0);
     416                break;
     417
     418                /* 0x1b, 0x5b is used by other keys/sequences */
     419
     420        case 0x5d:
     421                vt100_key(vt, KM_ALT, KC_RBRACKET, 0);
     422                break;
     423
     424        case 0x61:
     425                vt100_key(vt, KM_ALT, KC_A, 0);
     426                break;
     427        case 0x73:
     428                vt100_key(vt, KM_ALT, KC_S, 0);
     429                break;
     430        case 0x64:
     431                vt100_key(vt, KM_ALT, KC_D, 0);
     432                break;
     433        case 0x66:
     434                vt100_key(vt, KM_ALT, KC_F, 0);
     435                break;
     436        case 0x67:
     437                vt100_key(vt, KM_ALT, KC_G, 0);
     438                break;
     439        case 0x68:
     440                vt100_key(vt, KM_ALT, KC_H, 0);
     441                break;
     442        case 0x6a:
     443                vt100_key(vt, KM_ALT, KC_J, 0);
     444                break;
     445        case 0x6b:
     446                vt100_key(vt, KM_ALT, KC_K, 0);
     447                break;
     448        case 0x6c:
     449                vt100_key(vt, KM_ALT, KC_L, 0);
     450                break;
     451
     452        case 0x3b:
     453                vt100_key(vt, KM_ALT, KC_SEMICOLON, 0);
     454                break;
     455        case 0x27:
     456                vt100_key(vt, KM_ALT, KC_QUOTE, 0);
     457                break;
     458        case 0x5c:
     459                vt100_key(vt, KM_ALT, KC_BACKSLASH, 0);
     460                break;
     461
     462        case 0x7a:
     463                vt100_key(vt, KM_ALT, KC_Z, 0);
     464                break;
     465        case 0x78:
     466                vt100_key(vt, KM_ALT, KC_X, 0);
     467                break;
     468        case 0x63:
     469                vt100_key(vt, KM_ALT, KC_C, 0);
     470                break;
     471        case 0x76:
     472                vt100_key(vt, KM_ALT, KC_V, 0);
     473                break;
     474        case 0x62:
     475                vt100_key(vt, KM_ALT, KC_B, 0);
     476                break;
     477        case 0x6e:
     478                vt100_key(vt, KM_ALT, KC_N, 0);
     479                break;
     480        case 0x6d:
     481                vt100_key(vt, KM_ALT, KC_M, 0);
     482                break;
     483
     484        case 0x2c:
     485                vt100_key(vt, KM_ALT, KC_COMMA, 0);
     486                break;
     487        case 0x2e:
     488                vt100_key(vt, KM_ALT, KC_PERIOD, 0);
     489                break;
     490        case 0x2f:
     491                vt100_key(vt, KM_ALT, KC_SLASH, 0);
     492                break;
     493
     494        case 0x4f:
     495                vt->state = vts_1b4f;
     496                break;
     497        case 0x5b:
     498                vt->state = vts_1b5b;
     499                break;
     500        default:
     501                vt->state = vts_base;
     502                break;
     503        }
     504}
     505
     506/** Process input character with prefix 1b 4f.
     507 *
     508 * @param vt VT instance
     509 * @param c Input character
     510 */
     511static void vt100_rcvd_1b4f(vt100_t *vt, char c)
     512{
     513        switch (c) {
     514        case 0x50:
     515                vt100_key(vt, 0, KC_F1, 0);
     516                break;
     517        case 0x51:
     518                vt100_key(vt, 0, KC_F2, 0);
     519                break;
     520        case 0x52:
     521                vt100_key(vt, 0, KC_F3, 0);
     522                break;
     523        case 0x53:
     524                vt100_key(vt, 0, KC_F4, 0);
     525                break;
     526        case 0x48:
     527                vt100_key(vt, 0, KC_HOME, 0);
     528                break;
     529        case 0x46:
     530                vt100_key(vt, 0, KC_END, 0);
     531                break;
     532        default:
     533                vt->state = vts_base;
     534                break;
     535        }
     536}
     537
     538/** Process input character with prefix 1b 5b.
     539 *
     540 * @param vt VT instance
     541 * @param c Input character
     542 */
     543static void vt100_rcvd_1b5b(vt100_t *vt, char c)
     544{
     545        switch (c) {
     546        case 0x31:
     547                vt->state = vts_1b5b31;
     548                break;
     549        case 0x32:
     550                vt->state = vts_1b5b32;
     551                break;
     552        case 0x35:
     553                vt->state = vts_1b5b35;
     554                break;
     555        case 0x33:
     556                vt->state = vts_1b5b33;
     557                break;
     558        case 0x36:
     559                vt->state = vts_1b5b36;
     560                break;
     561        case 0x41:
     562                vt100_key(vt, 0, KC_UP, 0);
     563                break;
     564        case 0x44:
     565                vt100_key(vt, 0, KC_LEFT, 0);
     566                break;
     567        case 0x42:
     568                vt100_key(vt, 0, KC_DOWN, 0);
     569                break;
     570        case 0x43:
     571                vt100_key(vt, 0, KC_RIGHT, 0);
     572                break;
     573        case 0x48:
     574                vt100_key(vt, 0, KC_HOME, 0);
     575                break;
     576        case 0x46:
     577                vt100_key(vt, 0, KC_END, 0);
     578                break;
     579        default:
     580                vt->state = vts_base;
     581                break;
     582        }
     583}
     584
     585/** Process input character with prefix 1b 5b 31.
     586 *
     587 * @param vt VT instance
     588 * @param c Input character
     589 */
     590static void vt100_rcvd_1b5b31(vt100_t *vt, char c)
     591{
     592        switch (c) {
     593        case 0x35:
     594                vt->state = vts_1b5b3135;
     595                break;
     596        case 0x37:
     597                vt->state = vts_1b5b3137;
     598                break;
     599        case 0x38:
     600                vt->state = vts_1b5b3138;
     601                break;
     602        case 0x39:
     603                vt->state = vts_1b5b3139;
     604                break;
     605        default:
     606                vt->state = vts_base;
     607                break;
     608        }
     609}
     610
     611/** Process input character with prefix 1b 5b 31 35.
     612 *
     613 * @param vt VT instance
     614 * @param c Input character
     615 */
     616static void vt100_rcvd_1b5b3135(vt100_t *vt, char c)
     617{
     618        switch (c) {
     619        case 0x7e:
     620                vt100_key(vt, 0, KC_F5, 0);
     621                break;
     622        default:
     623                vt->state = vts_base;
     624                break;
     625        }
     626}
     627
     628/** Process input character with prefix 1b 5b 31 37.
     629 *
     630 * @param vt VT instance
     631 * @param c Input character
     632 */
     633static void vt100_rcvd_1b5b3137(vt100_t *vt, char c)
     634{
     635        switch (c) {
     636        case 0x7e:
     637                vt100_key(vt, 0, KC_F6, 0);
     638                break;
     639        default:
     640                vt->state = vts_base;
     641                break;
     642        }
     643}
     644
     645/** Process input character with prefix 1b 5b 31 38.
     646 *
     647 * @param vt VT instance
     648 * @param c Input character
     649 */
     650static void vt100_rcvd_1b5b3138(vt100_t *vt, char c)
     651{
     652        switch (c) {
     653        case 0x7e:
     654                vt100_key(vt, 0, KC_F7, 0);
     655                break;
     656        default:
     657                vt->state = vts_base;
     658                break;
     659        }
     660}
     661
     662/** Process input character with prefix 1b 5b 31 39.
     663 *
     664 * @param vt VT instance
     665 * @param c Input character
     666 */
     667static void vt100_rcvd_1b5b3139(vt100_t *vt, char c)
     668{
     669        switch (c) {
     670        case 0x7e:
     671                vt100_key(vt, 0, KC_F8, 0);
     672                break;
     673        default:
     674                vt->state = vts_base;
     675                break;
     676        }
     677}
     678
     679/** Process input character with prefix 1b 5b 32.
     680 *
     681 * @param vt VT instance
     682 * @param c Input character
     683 */
     684static void vt100_rcvd_1b5b32(vt100_t *vt, char c)
     685{
     686        switch (c) {
     687        case 0x30:
     688                vt->state = vts_1b5b3230;
     689                break;
     690        case 0x31:
     691                vt->state = vts_1b5b3231;
     692                break;
     693        case 0x33:
     694                vt->state = vts_1b5b3233;
     695                break;
     696        case 0x34:
     697                vt->state = vts_1b5b3234;
     698                break;
     699        case 0x35:
     700                vt->state = vts_1b5b3235;
     701                break;
     702        case 0x38:
     703                vt->state = vts_1b5b3238;
     704                break;
     705        case 0x7e:
     706                vt100_key(vt, 0, KC_INSERT, 0);
     707                break;
     708        default:
     709                vt->state = vts_base;
     710                break;
     711        }
     712}
     713
     714/** Process input character with prefix 1b 5b 32 30.
     715 *
     716 * @param vt VT instance
     717 * @param c Input character
     718 */
     719static void vt100_rcvd_1b5b3230(vt100_t *vt, char c)
     720{
     721        switch (c) {
     722        case 0x7e:
     723                vt100_key(vt, 0, KC_F9, 0);
     724                break;
     725        default:
     726                vt->state = vts_base;
     727                break;
     728        }
     729}
     730
     731/** Process input character with prefix 1b 5b 32 31.
     732 *
     733 * @param vt VT instance
     734 * @param c Input character
     735 */
     736static void vt100_rcvd_1b5b3231(vt100_t *vt, char c)
     737{
     738        switch (c) {
     739        case 0x7e:
     740                vt100_key(vt, 0, KC_F10, 0);
     741                break;
     742        default:
     743                vt->state = vts_base;
     744                break;
     745        }
     746}
     747
     748/** Process input character with prefix 1b 5b 32 33.
     749 *
     750 * @param vt VT instance
     751 * @param c Input character
     752 */
     753static void vt100_rcvd_1b5b3233(vt100_t *vt, char c)
     754{
     755        switch (c) {
     756        case 0x7e:
     757                vt100_key(vt, 0, KC_F11, 0);
     758                break;
     759        default:
     760                vt->state = vts_base;
     761                break;
     762        }
     763}
     764
     765/** Process input character with prefix 1b 5b 32 34.
     766 *
     767 * @param vt VT instance
     768 * @param c Input character
     769 */
     770static void vt100_rcvd_1b5b3234(vt100_t *vt, char c)
     771{
     772        switch (c) {
     773        case 0x7e:
     774                vt100_key(vt, 0, KC_F12, 0);
     775                break;
     776        default:
     777                vt->state = vts_base;
     778                break;
     779        }
     780}
     781
     782/** Process input character with prefix 1b 5b 32 35.
     783 *
     784 * @param vt VT instance
     785 * @param c Input character
     786 */
     787static void vt100_rcvd_1b5b3235(vt100_t *vt, char c)
     788{
     789        switch (c) {
     790        case 0x7e:
     791                vt100_key(vt, 0, KC_PRTSCR, 0);
     792                break;
     793        default:
     794                vt->state = vts_base;
     795                break;
     796        }
     797}
     798
     799/** Process input character with prefix 1b 5b 32 38.
     800 *
     801 * @param vt VT instance
     802 * @param c Input character
     803 */
     804static void vt100_rcvd_1b5b3238(vt100_t *vt, char c)
     805{
     806        switch (c) {
     807        case 0x7e:
     808                vt100_key(vt, 0, KC_PAUSE, 0);
     809                break;
     810        default:
     811                vt->state = vts_base;
     812                break;
     813        }
     814}
     815
     816/** Process input character with prefix 1b 5b 35.
     817 *
     818 * @param vt VT instance
     819 * @param c Input character
     820 */
     821static void vt100_rcvd_1b5b35(vt100_t *vt, char c)
     822{
     823        switch (c) {
     824        case 0x7e:
     825                vt100_key(vt, 0, KC_PAGE_UP, 0);
     826                break;
     827        default:
     828                vt->state = vts_base;
     829                break;
     830        }
     831}
     832
     833/** Process input character with prefix 1b 5b 33.
     834 *
     835 * @param vt VT instance
     836 * @param c Input character
     837 */
     838static void vt100_rcvd_1b5b33(vt100_t *vt, char c)
     839{
     840        switch (c) {
     841        case 0x7e:
     842                vt100_key(vt, 0, KC_DELETE, 0);
     843                break;
     844        default:
     845                vt->state = vts_base;
     846                break;
     847        }
     848}
     849
     850/** Process input character with prefix 1b 5b 36.
     851 *
     852 * @param vt VT instance
     853 * @param c Input character
     854 */
     855static void vt100_rcvd_1b5b36(vt100_t *vt, char c)
     856{
     857        switch (c) {
     858        case 0x7e:
     859                vt100_key(vt, 0, KC_PAGE_DOWN, 0);
     860                break;
     861        default:
     862                vt->state = vts_base;
     863                break;
     864        }
     865}
     866
     867/** Process input character (base state, no prefix).
     868 *
     869 * @param vt VT instance
     870 * @param c Input character
     871 */
     872static void vt100_rcvd_base(vt100_t *vt, char c)
     873{
     874        switch (c) {
     875                /*
     876                 * Not shifted
     877                 */
     878        case 0x60:
     879                vt100_key(vt, 0, KC_BACKTICK, c);
     880                break;
     881
     882        case 0x31:
     883                vt100_key(vt, 0, KC_1, c);
     884                break;
     885        case 0x32:
     886                vt100_key(vt, 0, KC_2, c);
     887                break;
     888        case 0x33:
     889                vt100_key(vt, 0, KC_3, c);
     890                break;
     891        case 0x34:
     892                vt100_key(vt, 0, KC_4, c);
     893                break;
     894        case 0x35:
     895                vt100_key(vt, 0, KC_5, c);
     896                break;
     897        case 0x36:
     898                vt100_key(vt, 0, KC_6, c);
     899                break;
     900        case 0x37:
     901                vt100_key(vt, 0, KC_7, c);
     902                break;
     903        case 0x38:
     904                vt100_key(vt, 0, KC_8, c);
     905                break;
     906        case 0x39:
     907                vt100_key(vt, 0, KC_9, c);
     908                break;
     909        case 0x30:
     910                vt100_key(vt, 0, KC_0, c);
     911                break;
     912        case 0x2d:
     913                vt100_key(vt, 0, KC_MINUS, c);
     914                break;
     915        case 0x3d:
     916                vt100_key(vt, 0, KC_EQUALS, c);
     917                break;
     918
     919        case 0x08:
     920                vt100_key(vt, 0, KC_BACKSPACE, c);
     921                break;
     922
     923        case 0x09:
     924                vt100_key(vt, 0, KC_TAB, c);
     925                break;
     926
     927        case 0x71:
     928                vt100_key(vt, 0, KC_Q, c);
     929                break;
     930        case 0x77:
     931                vt100_key(vt, 0, KC_W, c);
     932                break;
     933        case 0x65:
     934                vt100_key(vt, 0, KC_E, c);
     935                break;
     936        case 0x72:
     937                vt100_key(vt, 0, KC_R, c);
     938                break;
     939        case 0x74:
     940                vt100_key(vt, 0, KC_T, c);
     941                break;
     942        case 0x79:
     943                vt100_key(vt, 0, KC_Y, c);
     944                break;
     945        case 0x75:
     946                vt100_key(vt, 0, KC_U, c);
     947                break;
     948        case 0x69:
     949                vt100_key(vt, 0, KC_I, c);
     950                break;
     951        case 0x6f:
     952                vt100_key(vt, 0, KC_O, c);
     953                break;
     954        case 0x70:
     955                vt100_key(vt, 0, KC_P, c);
     956                break;
     957
     958        case 0x5b:
     959                vt100_key(vt, 0, KC_LBRACKET, c);
     960                break;
     961        case 0x5d:
     962                vt100_key(vt, 0, KC_RBRACKET, c);
     963                break;
     964
     965        case 0x61:
     966                vt100_key(vt, 0, KC_A, c);
     967                break;
     968        case 0x73:
     969                vt100_key(vt, 0, KC_S, c);
     970                break;
     971        case 0x64:
     972                vt100_key(vt, 0, KC_D, c);
     973                break;
     974        case 0x66:
     975                vt100_key(vt, 0, KC_F, c);
     976                break;
     977        case 0x67:
     978                vt100_key(vt, 0, KC_G, c);
     979                break;
     980        case 0x68:
     981                vt100_key(vt, 0, KC_H, c);
     982                break;
     983        case 0x6a:
     984                vt100_key(vt, 0, KC_J, c);
     985                break;
     986        case 0x6b:
     987                vt100_key(vt, 0, KC_K, c);
     988                break;
     989        case 0x6c:
     990                vt100_key(vt, 0, KC_L, c);
     991                break;
     992
     993        case 0x3b:
     994                vt100_key(vt, 0, KC_SEMICOLON, c);
     995                break;
     996        case 0x27:
     997                vt100_key(vt, 0, KC_QUOTE, c);
     998                break;
     999        case 0x5c:
     1000                vt100_key(vt, 0, KC_BACKSLASH, c);
     1001                break;
     1002
     1003        case 0x7a:
     1004                vt100_key(vt, 0, KC_Z, c);
     1005                break;
     1006        case 0x78:
     1007                vt100_key(vt, 0, KC_X, c);
     1008                break;
     1009        case 0x63:
     1010                vt100_key(vt, 0, KC_C, c);
     1011                break;
     1012        case 0x76:
     1013                vt100_key(vt, 0, KC_V, c);
     1014                break;
     1015        case 0x62:
     1016                vt100_key(vt, 0, KC_B, c);
     1017                break;
     1018        case 0x6e:
     1019                vt100_key(vt, 0, KC_N, c);
     1020                break;
     1021        case 0x6d:
     1022                vt100_key(vt, 0, KC_M, c);
     1023                break;
     1024
     1025        case 0x2c:
     1026                vt100_key(vt, 0, KC_COMMA, c);
     1027                break;
     1028        case 0x2e:
     1029                vt100_key(vt, 0, KC_PERIOD, c);
     1030                break;
     1031        case 0x2f:
     1032                vt100_key(vt, 0, KC_SLASH, c);
     1033                break;
     1034
     1035                /*
     1036                 * Shifted
     1037                 */
     1038        case 0x7e:
     1039                vt100_key(vt, KM_SHIFT, KC_BACKTICK, c);
     1040                break;
     1041
     1042        case 0x21:
     1043                vt100_key(vt, KM_SHIFT, KC_1, c);
     1044                break;
     1045        case 0x40:
     1046                vt100_key(vt, KM_SHIFT, KC_2, c);
     1047                break;
     1048        case 0x23:
     1049                vt100_key(vt, KM_SHIFT, KC_3, c);
     1050                break;
     1051        case 0x24:
     1052                vt100_key(vt, KM_SHIFT, KC_4, c);
     1053                break;
     1054        case 0x25:
     1055                vt100_key(vt, KM_SHIFT, KC_5, c);
     1056                break;
     1057        case 0x5e:
     1058                vt100_key(vt, KM_SHIFT, KC_6, c);
     1059                break;
     1060        case 0x26:
     1061                vt100_key(vt, KM_SHIFT, KC_7, c);
     1062                break;
     1063        case 0x2a:
     1064                vt100_key(vt, KM_SHIFT, KC_8, c);
     1065                break;
     1066        case 0x28:
     1067                vt100_key(vt, KM_SHIFT, KC_9, c);
     1068                break;
     1069        case 0x29:
     1070                vt100_key(vt, KM_SHIFT, KC_0, c);
     1071                break;
     1072        case 0x5f:
     1073                vt100_key(vt, KM_SHIFT, KC_MINUS, c);
     1074                break;
     1075        case 0x2b:
     1076                vt100_key(vt, KM_SHIFT, KC_EQUALS, c);
     1077                break;
     1078
     1079        case 0x51:
     1080                vt100_key(vt, KM_SHIFT, KC_Q, c);
     1081                break;
     1082        case 0x57:
     1083                vt100_key(vt, KM_SHIFT, KC_W, c);
     1084                break;
     1085        case 0x45:
     1086                vt100_key(vt, KM_SHIFT, KC_E, c);
     1087                break;
     1088        case 0x52:
     1089                vt100_key(vt, KM_SHIFT, KC_R, c);
     1090                break;
     1091        case 0x54:
     1092                vt100_key(vt, KM_SHIFT, KC_T, c);
     1093                break;
     1094        case 0x59:
     1095                vt100_key(vt, KM_SHIFT, KC_Y, c);
     1096                break;
     1097        case 0x55:
     1098                vt100_key(vt, KM_SHIFT, KC_U, c);
     1099                break;
     1100        case 0x49:
     1101                vt100_key(vt, KM_SHIFT, KC_I, c);
     1102                break;
     1103        case 0x4f:
     1104                vt100_key(vt, KM_SHIFT, KC_O, c);
     1105                break;
     1106        case 0x50:
     1107                vt100_key(vt, KM_SHIFT, KC_P, c);
     1108                break;
     1109
     1110        case 0x7b:
     1111                vt100_key(vt, KM_SHIFT, KC_LBRACKET, c);
     1112                break;
     1113        case 0x7d:
     1114                vt100_key(vt, KM_SHIFT, KC_RBRACKET, c);
     1115                break;
     1116
     1117        case 0x41:
     1118                vt100_key(vt, KM_SHIFT, KC_A, c);
     1119                break;
     1120        case 0x53:
     1121                vt100_key(vt, KM_SHIFT, KC_S, c);
     1122                break;
     1123        case 0x44:
     1124                vt100_key(vt, KM_SHIFT, KC_D, c);
     1125                break;
     1126        case 0x46:
     1127                vt100_key(vt, KM_SHIFT, KC_F, c);
     1128                break;
     1129        case 0x47:
     1130                vt100_key(vt, KM_SHIFT, KC_G, c);
     1131                break;
     1132        case 0x48:
     1133                vt100_key(vt, KM_SHIFT, KC_H, c);
     1134                break;
     1135        case 0x4a:
     1136                vt100_key(vt, KM_SHIFT, KC_J, c);
     1137                break;
     1138        case 0x4b:
     1139                vt100_key(vt, KM_SHIFT, KC_K, c);
     1140                break;
     1141        case 0x4c:
     1142                vt100_key(vt, KM_SHIFT, KC_L, c);
     1143                break;
     1144
     1145        case 0x3a:
     1146                vt100_key(vt, KM_SHIFT, KC_SEMICOLON, c);
     1147                break;
     1148        case 0x22:
     1149                vt100_key(vt, KM_SHIFT, KC_QUOTE, c);
     1150                break;
     1151        case 0x7c:
     1152                vt100_key(vt, KM_SHIFT, KC_BACKSLASH, c);
     1153                break;
     1154
     1155        case 0x5a:
     1156                vt100_key(vt, KM_SHIFT, KC_Z, c);
     1157                break;
     1158        case 0x58:
     1159                vt100_key(vt, KM_SHIFT, KC_X, c);
     1160                break;
     1161        case 0x43:
     1162                vt100_key(vt, KM_SHIFT, KC_C, c);
     1163                break;
     1164        case 0x56:
     1165                vt100_key(vt, KM_SHIFT, KC_V, c);
     1166                break;
     1167        case 0x42:
     1168                vt100_key(vt, KM_SHIFT, KC_B, c);
     1169                break;
     1170        case 0x4e:
     1171                vt100_key(vt, KM_SHIFT, KC_N, c);
     1172                break;
     1173        case 0x4d:
     1174                vt100_key(vt, KM_SHIFT, KC_M, c);
     1175                break;
     1176
     1177        case 0x3c:
     1178                vt100_key(vt, KM_SHIFT, KC_COMMA, c);
     1179                break;
     1180        case 0x3e:
     1181                vt100_key(vt, KM_SHIFT, KC_PERIOD, c);
     1182                break;
     1183        case 0x3f:
     1184                vt100_key(vt, KM_SHIFT, KC_SLASH, c);
     1185                break;
     1186
     1187                /*
     1188                 * ...
     1189                 */
     1190        case 0x20:
     1191                vt100_key(vt, 0, KC_SPACE, c);
     1192                break;
     1193        case 0x0a:
     1194                vt100_key(vt, 0, KC_ENTER, '\n');
     1195                break;
     1196        case 0x0d:
     1197                vt100_key(vt, 0, KC_ENTER, '\n');
     1198                break;
     1199
     1200                /*
     1201                 * Ctrl + key
     1202                 */
     1203        case 0x11:
     1204                vt100_key(vt, KM_CTRL, KC_Q, c);
     1205                break;
     1206        case 0x17:
     1207                vt100_key(vt, KM_CTRL, KC_W, c);
     1208                break;
     1209        case 0x05:
     1210                vt100_key(vt, KM_CTRL, KC_E, c);
     1211                break;
     1212        case 0x12:
     1213                vt100_key(vt, KM_CTRL, KC_R, c);
     1214                break;
     1215        case 0x14:
     1216                vt100_key(vt, KM_CTRL, KC_T, c);
     1217                break;
     1218        case 0x19:
     1219                vt100_key(vt, KM_CTRL, KC_Y, c);
     1220                break;
     1221        case 0x15:
     1222                vt100_key(vt, KM_CTRL, KC_U, c);
     1223                break;
     1224        case 0x0f:
     1225                vt100_key(vt, KM_CTRL, KC_O, c);
     1226                break;
     1227        case 0x10:
     1228                vt100_key(vt, KM_CTRL, KC_P, c);
     1229                break;
     1230
     1231        case 0x01:
     1232                vt100_key(vt, KM_CTRL, KC_A, c);
     1233                break;
     1234        case 0x13:
     1235                vt100_key(vt, KM_CTRL, KC_S, c);
     1236                break;
     1237        case 0x04:
     1238                vt100_key(vt, KM_CTRL, KC_D, c);
     1239                break;
     1240        case 0x06:
     1241                vt100_key(vt, KM_CTRL, KC_F, c);
     1242                break;
     1243        case 0x07:
     1244                vt100_key(vt, KM_CTRL, KC_G, c);
     1245                break;
     1246        case 0x0b:
     1247                vt100_key(vt, KM_CTRL, KC_K, c);
     1248                break;
     1249        case 0x0c:
     1250                vt100_key(vt, KM_CTRL, KC_L, c);
     1251                break;
     1252
     1253        case 0x1a:
     1254                vt100_key(vt, KM_CTRL, KC_Z, c);
     1255                break;
     1256        case 0x18:
     1257                vt100_key(vt, KM_CTRL, KC_X, c);
     1258                break;
     1259        case 0x03:
     1260                vt100_key(vt, KM_CTRL, KC_C, c);
     1261                break;
     1262        case 0x16:
     1263                vt100_key(vt, KM_CTRL, KC_V, c);
     1264                break;
     1265        case 0x02:
     1266                vt100_key(vt, KM_CTRL, KC_B, c);
     1267                break;
     1268        case 0x0e:
     1269                vt100_key(vt, KM_CTRL, KC_N, c);
     1270                break;
     1271
     1272        case 0x7f:
     1273                vt100_key(vt, 0, KC_BACKSPACE, '\b');
     1274                break;
     1275
     1276        case 0x1b:
     1277                vt->state = vts_1b;
     1278                break;
     1279        }
     1280}
     1281
     1282void vt100_rcvd_char(vt100_t *vt, char c)
     1283{
     1284        switch (vt->state) {
     1285        case vts_base:
     1286                vt100_rcvd_base(vt, c);
     1287                break;
     1288        case vts_1b:
     1289                vt100_rcvd_1b(vt, c);
     1290                break;
     1291        case vts_1b4f:
     1292                vt100_rcvd_1b4f(vt, c);
     1293                break;
     1294        case vts_1b5b:
     1295                vt100_rcvd_1b5b(vt, c);
     1296                break;
     1297        case vts_1b5b31:
     1298                vt100_rcvd_1b5b31(vt, c);
     1299                break;
     1300        case vts_1b5b3135:
     1301                vt100_rcvd_1b5b3135(vt, c);
     1302                break;
     1303        case vts_1b5b3137:
     1304                vt100_rcvd_1b5b3137(vt, c);
     1305                break;
     1306        case vts_1b5b3138:
     1307                vt100_rcvd_1b5b3138(vt, c);
     1308                break;
     1309        case vts_1b5b3139:
     1310                vt100_rcvd_1b5b3139(vt, c);
     1311                break;
     1312        case vts_1b5b32:
     1313                vt100_rcvd_1b5b32(vt, c);
     1314                break;
     1315        case vts_1b5b3230:
     1316                vt100_rcvd_1b5b3230(vt, c);
     1317                break;
     1318        case vts_1b5b3231:
     1319                vt100_rcvd_1b5b3231(vt, c);
     1320                break;
     1321        case vts_1b5b3233:
     1322                vt100_rcvd_1b5b3233(vt, c);
     1323                break;
     1324        case vts_1b5b3234:
     1325                vt100_rcvd_1b5b3234(vt, c);
     1326                break;
     1327        case vts_1b5b3235:
     1328                vt100_rcvd_1b5b3235(vt, c);
     1329                break;
     1330        case vts_1b5b3238:
     1331                vt100_rcvd_1b5b3238(vt, c);
     1332                break;
     1333        case vts_1b5b35:
     1334                vt100_rcvd_1b5b35(vt, c);
     1335                break;
     1336        case vts_1b5b33:
     1337                vt100_rcvd_1b5b33(vt, c);
     1338                break;
     1339        case vts_1b5b36:
     1340                vt100_rcvd_1b5b36(vt, c);
     1341                break;
     1342        }
    2341343}
    2351344
  • uspace/srv/hid/remcons/remcons.c

    rd31c3ea r6907f26  
    3434 */
    3535
     36#include <adt/prodcons.h>
    3637#include <as.h>
    3738#include <async.h>
     
    124125static void remcons_vt_cputs(void *, const char *);
    125126static void remcons_vt_flush(void *);
     127static void remcons_vt_key(void *, keymod_t, keycode_t, char);
    126128
    127129static vt100_cb_t remcons_vt_cb = {
    128130        .putuchar = remcons_vt_putchar,
    129131        .control_puts = remcons_vt_cputs,
    130         .flush = remcons_vt_flush
     132        .flush = remcons_vt_flush,
     133        .key = remcons_vt_key
    131134};
    132135
     
    340343}
    341344
     345/** Creates new keyboard event from given char.
     346 *
     347 * @param type Event type (press / release).
     348 * @param c Pressed character.
     349 */
     350static kbd_event_t *new_kbd_event(kbd_event_type_t type, keymod_t mods,
     351    keycode_t key, char c)
     352{
     353        kbd_event_t *event = malloc(sizeof(kbd_event_t));
     354        assert(event);
     355
     356        link_initialize(&event->link);
     357        event->type = type;
     358        event->mods = mods;
     359        event->key = key;
     360        event->c = c;
     361
     362        return event;
     363}
     364
    342365static errno_t remcons_get_event(con_srv_t *srv, cons_event_t *event)
    343366{
     367        remcons_t *remcons = srv_to_remcons(srv);
    344368        telnet_user_t *user = srv_to_user(srv);
    345         kbd_event_t kevent;
    346         errno_t rc;
    347 
    348         rc = telnet_user_get_next_keyboard_event(user, &kevent);
    349         if (rc != EOK) {
    350                 /* XXX What? */
    351                 memset(event, 0, sizeof(*event));
    352                 return EOK;
    353         }
     369        size_t nread;
     370
     371        while (list_empty(&remcons->in_events.list)) {
     372                char next_byte = 0;
     373
     374                errno_t rc = telnet_user_recv(user, &next_byte, 1,
     375                    &nread);
     376                if (rc != EOK)
     377                        return rc;
     378
     379                vt100_rcvd_char(remcons->vt, next_byte);
     380        }
     381
     382        link_t *link = prodcons_consume(&remcons->in_events);
     383        kbd_event_t *tmp = list_get_instance(link, kbd_event_t, link);
    354384
    355385        event->type = CEV_KEY;
    356         event->ev.key = kevent;
     386        event->ev.key = *tmp;
     387
     388        free(tmp);
    357389
    358390        return EOK;
     
    551583}
    552584
     585static void remcons_vt_key(void *arg, keymod_t mods, keycode_t key, char c)
     586{
     587        remcons_t *remcons = (remcons_t *)arg;
     588
     589        kbd_event_t *down = new_kbd_event(KEY_PRESS, mods, key, c);
     590        kbd_event_t *up = new_kbd_event(KEY_RELEASE, mods, key, c);
     591        assert(down);
     592        assert(up);
     593        prodcons_produce(&remcons->in_events, &down->link);
     594        prodcons_produce(&remcons->in_events, &up->link);
     595}
     596
    553597/** Handle network connection.
    554598 *
     
    567611        remcons->enable_rgb = !no_ctl && !no_rgb;
    568612        remcons->user = user;
     613        prodcons_initialize(&remcons->in_events);
    569614
    570615        if (remcons->enable_ctl) {
  • uspace/srv/hid/remcons/remcons.h

    rd31c3ea r6907f26  
    3737#define REMCONS_H_
    3838
     39#include <adt/prodcons.h>
    3940#include <stdbool.h>
    4041#include <vt/vt100.h>
     
    5455        charfield_t *ubuf;      /**< user buffer */
    5556        bool curs_visible;      /**< cursor is visible */
     57
     58        /** Producer-consumer of kbd_event_t. */
     59        prodcons_t in_events;
    5660} remcons_t;
    5761
  • uspace/srv/hid/remcons/user.c

    rd31c3ea r6907f26  
    8383        user->conn = conn;
    8484        user->service_id = (service_id_t) -1;
    85         prodcons_initialize(&user->in_events);
    8685        link_initialize(&user->link);
    8786        user->socket_buffer_len = 0;
     
    211210}
    212211
    213 /** Receive next byte from a socket (use buffering.
    214  * We need to return the value via extra argument because the read byte
    215  * might be negative.
     212/** Receive next byte from a socket (use buffering).
     213 *
     214 * @param user Telnet user
     215 * @param byte Place to store the received byte
     216 * @return EOK on success or an error code
    216217 */
    217218static errno_t telnet_user_recv_next_byte_locked(telnet_user_t *user, char *byte)
     
    230231}
    231232
    232 errno_t telnet_user_recv(telnet_user_t *user, void *data, size_t size,
    233     size_t *nread)
    234 {
    235         errno_t rc;
    236         size_t nb;
    237 
    238         /* No more buffered data? */
    239         if (user->socket_buffer_len <= user->socket_buffer_pos) {
    240                 rc = telnet_user_fill_recv_buf(user);
    241                 if (rc != EOK)
    242                         return rc;
    243         }
    244 
    245         nb = user->socket_buffer_len - user->socket_buffer_pos;
    246         memcpy(data, user->socket_buffer + user->socket_buffer_pos, nb);
    247         user->socket_buffer_pos += nb;
    248         *nread = nb;
    249         return EOK;
    250 }
    251 
    252 /** Creates new keyboard event from given char.
    253  *
    254  * @param type Event type (press / release).
    255  * @param c Pressed character.
    256  */
    257 static kbd_event_t *new_kbd_event(kbd_event_type_t type, char32_t c)
    258 {
    259         kbd_event_t *event = malloc(sizeof(kbd_event_t));
    260         assert(event);
    261 
    262         link_initialize(&event->link);
    263         event->type = type;
    264         event->c = c;
    265         event->mods = 0;
    266 
    267         switch (c) {
    268         case '\n':
    269                 event->key = KC_ENTER;
    270                 break;
    271         case '\t':
    272                 event->key = KC_TAB;
    273                 break;
    274         case '\b':
    275         case 127: /* This is what Linux telnet sends. */
    276                 event->key = KC_BACKSPACE;
    277                 event->c = '\b';
    278                 break;
    279         default:
    280                 event->key = KC_A;
    281                 break;
    282         }
    283 
    284         return event;
     233/** Determine if a received byte is available without waiting.
     234 *
     235 * @param user Telnet user
     236 * @return @c true iff a byte is currently available
     237 */
     238static bool telnet_user_byte_avail(telnet_user_t *user)
     239{
     240        return user->socket_buffer_len > user->socket_buffer_pos;
    285241}
    286242
     
    303259}
    304260
    305 /** Get next keyboard event.
     261/** Receive data from telnet connection.
    306262 *
    307263 * @param user Telnet user.
    308  * @param event Where to store the keyboard event.
    309  * @return Error code.
    310  */
    311 errno_t telnet_user_get_next_keyboard_event(telnet_user_t *user, kbd_event_t *event)
    312 {
    313         fibril_mutex_lock(&user->guard);
    314         if (list_empty(&user->in_events.list)) {
     264 * @param buf Destination buffer
     265 * @param size Buffer size
     266 * @param nread Place to store number of bytes read (>0 on success)
     267 * @return EOK on success or an error code
     268 */
     269errno_t telnet_user_recv(telnet_user_t *user, void *buf, size_t size,
     270    size_t *nread)
     271{
     272        uint8_t *bp = (uint8_t *)buf;
     273        fibril_mutex_lock(&user->guard);
     274
     275        assert(size > 0);
     276        *nread = 0;
     277
     278        do {
    315279                char next_byte = 0;
    316280                bool inside_telnet_command = false;
     
    319283
    320284                /* Skip zeros, bail-out on error. */
    321                 while (next_byte == 0) {
    322                         fibril_mutex_unlock(&user->guard);
    323 
    324                         errno_t rc = telnet_user_recv_next_byte_locked(user, &next_byte);
    325                         if (rc != EOK)
     285                do {
     286                        errno_t rc = telnet_user_recv_next_byte_locked(user,
     287                            &next_byte);
     288                        if (rc != EOK) {
     289                                fibril_mutex_unlock(&user->guard);
    326290                                return rc;
    327 
     291                        }
    328292                        uint8_t byte = (uint8_t) next_byte;
    329                         fibril_mutex_lock(&user->guard);
    330293
    331294                        /* Skip telnet commands. */
     
    345308                                next_byte = 0;
    346309                        }
    347                 }
     310                } while (next_byte == 0 && telnet_user_byte_avail(user));
    348311
    349312                /* CR-LF conversions. */
     
    352315                }
    353316
    354                 kbd_event_t *down = new_kbd_event(KEY_PRESS, next_byte);
    355                 kbd_event_t *up = new_kbd_event(KEY_RELEASE, next_byte);
    356                 assert(down);
    357                 assert(up);
    358                 prodcons_produce(&user->in_events, &down->link);
    359                 prodcons_produce(&user->in_events, &up->link);
    360         }
    361 
    362         link_t *link = prodcons_consume(&user->in_events);
    363         kbd_event_t *tmp = list_get_instance(link, kbd_event_t, link);
    364 
    365         fibril_mutex_unlock(&user->guard);
    366 
    367         *event = *tmp;
    368 
    369         free(tmp);
    370 
     317                if (next_byte != 0) {
     318                        *bp++ = next_byte;
     319                        ++*nread;
     320                        --size;
     321                }
     322        } while (size > 0 && (telnet_user_byte_avail(user) || *nread == 0));
     323
     324        fibril_mutex_unlock(&user->guard);
    371325        return EOK;
    372326}
  • uspace/srv/hid/remcons/user.h

    rd31c3ea r6907f26  
    3737#define TELNET_USER_H_
    3838
    39 #include <adt/prodcons.h>
    4039#include <fibril_synch.h>
    4140#include <inet/tcp.h>
     
    6261        con_srvs_t srvs;
    6362
    64         /** Producer-consumer of kbd_event_t. */
    65         prodcons_t in_events;
    6663        link_t link;
    6764        char socket_buffer[BUFFER_SIZE];
Note: See TracChangeset for help on using the changeset viewer.