Changeset 6907f26 in mainline
- Timestamp:
- 2024-10-03T15:42:59Z (3 months ago)
- 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)
- Location:
- uspace
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/vt/include/vt/vt100.h
rd31c3ea r6907f26 36 36 37 37 #include <io/charfield.h> 38 #include <io/keycode.h> 38 39 #include <ipc/common.h> 39 40 #include <uchar.h> … … 75 76 void (*control_puts)(void *, const char *); 76 77 void (*flush)(void *); 78 void (*key)(void *, keymod_t, keycode_t, char); 77 79 } vt100_cb_t; 80 81 /** VT100 decoding state */ 82 typedef 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; 78 122 79 123 /** VT100 instance */ … … 98 142 /** Argument to callback functions */ 99 143 void *arg; 144 145 /** Input decoding state */ 146 vt100_state_t state; 100 147 } vt100_t; 101 148 … … 119 166 extern void vt100_flush(vt100_t *); 120 167 168 extern void vt100_rcvd_char(vt100_t *, char); 169 121 170 #endif 122 171 -
uspace/lib/vt/meson.build
rd31c3ea r6907f26 27 27 # 28 28 29 deps = [ ' output' ]29 deps = [ 'input', 'output' ] 30 30 src = files( 31 31 'src/vt100.c' -
uspace/lib/vt/src/vt100.c
rd31c3ea r6907f26 34 34 #include <errno.h> 35 35 #include <io/color.h> 36 #include <io/keycode.h> 36 37 #include <stdio.h> 37 38 #include <stdlib.h> 38 39 #include <vt/vt100.h> 39 40 41 /** Map console colors to VT100 color indices */ 40 42 sgr_color_index_t color_map[] = { 41 43 [COLOR_BLACK] = CI_BLACK, … … 49 51 }; 50 52 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 */ 57 void 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 */ 67 static void vt100_sgr(vt100_t *vt, unsigned int mode) 58 68 { 59 69 char control[MAX_CONTROL]; 60 70 61 71 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 */ 84 static void vt100_sgr5(vt100_t *vt, unsigned a1, unsigned a2, 67 85 unsigned a3, unsigned a4, unsigned a5) 68 86 { … … 71 89 snprintf(control, MAX_CONTROL, "\033[%u;%u;%u;%u;%um", 72 90 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 */ 100 void vt100_set_pos(vt100_t *vt, sysarg_t col, sysarg_t row) 77 101 { 78 102 char control[MAX_CONTROL]; … … 80 104 snprintf(control, MAX_CONTROL, "\033[%" PRIun ";%" PRIun "f", 81 105 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 */ 114 void vt100_set_sgr(vt100_t *vt, char_attrs_t attrs) 86 115 { 87 116 unsigned color; … … 91 120 switch (attrs.val.style) { 92 121 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); 96 125 break; 97 126 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); 102 131 break; 103 132 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); 107 136 break; 108 137 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); 112 141 break; 113 142 } 114 143 break; 115 144 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]); 119 148 120 149 if (attrs.val.index.attr & CATTR_BRIGHT) 121 vt100_sgr( state, SGR_BOLD);150 vt100_sgr(vt, SGR_BOLD); 122 151 123 152 break; 124 153 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), 127 156 GREEN(attrs.val.rgb.bgcolor), 128 157 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), 130 159 GREEN(attrs.val.rgb.fgcolor), 131 160 BLUE(attrs.val.rgb.fgcolor)); 132 161 } else { 133 vt100_sgr( state, SGR_RESET);162 vt100_sgr(vt, SGR_RESET); 134 163 color = 135 164 ((RED(attrs.val.rgb.fgcolor) >= 0x80) ? COLOR_RED : 0) | 136 165 ((GREEN(attrs.val.rgb.fgcolor) >= 0x80) ? COLOR_GREEN : 0) | 137 166 ((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]); 139 168 color = 140 169 ((RED(attrs.val.rgb.bgcolor) >= 0x80) ? COLOR_RED : 0) | 141 170 ((GREEN(attrs.val.rgb.bgcolor) >= 0x80) ? COLOR_GREEN : 0) | 142 171 ((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]); 144 173 } 145 174 break; … … 147 176 } 148 177 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 */ 149 187 vt100_t *vt100_create(void *arg, sysarg_t cols, sysarg_t rows, vt100_cb_t *cb) 150 188 { 151 vt100_t * state= malloc(sizeof(vt100_t));152 if ( state== NULL)189 vt100_t *vt = malloc(sizeof(vt100_t)); 190 if (vt == NULL) 153 191 return NULL; 154 192 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 */ 212 void 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 */ 223 void vt100_get_dimensions(vt100_t *vt, sysarg_t *cols, 176 224 sysarg_t *rows) 177 225 { 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 */ 235 errno_t vt100_yield(vt100_t *vt) 183 236 { 184 237 return EOK; 185 238 } 186 239 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 */ 245 errno_t vt100_claim(vt100_t *vt) 188 246 { 189 247 return EOK; 190 248 } 191 249 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 */ 256 void vt100_goto(vt100_t *vt, sysarg_t col, sysarg_t row) 257 { 258 if ((col >= vt->cols) || (row >= vt->rows)) 195 259 return; 196 260 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 */ 273 void 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 */ 286 void vt100_cursor_visibility(vt100_t *vt, bool visible) 213 287 { 214 288 if (visible) 215 state->cb->control_puts(state->arg, "\033[?25h");289 vt->cb->control_puts(vt->arg, "\033[?25h"); 216 290 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 */ 299 void 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 */ 314 void 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 */ 328 static 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 */ 339 static 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 */ 511 static 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 */ 543 static 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 */ 590 static 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 */ 616 static 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 */ 633 static 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 */ 650 static 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 */ 667 static 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 */ 684 static 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 */ 719 static 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 */ 736 static 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 */ 753 static 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 */ 770 static 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 */ 787 static 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 */ 804 static 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 */ 821 static 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 */ 838 static 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 */ 855 static 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 */ 872 static 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 1282 void 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 } 234 1343 } 235 1344 -
uspace/srv/hid/remcons/remcons.c
rd31c3ea r6907f26 34 34 */ 35 35 36 #include <adt/prodcons.h> 36 37 #include <as.h> 37 38 #include <async.h> … … 124 125 static void remcons_vt_cputs(void *, const char *); 125 126 static void remcons_vt_flush(void *); 127 static void remcons_vt_key(void *, keymod_t, keycode_t, char); 126 128 127 129 static vt100_cb_t remcons_vt_cb = { 128 130 .putuchar = remcons_vt_putchar, 129 131 .control_puts = remcons_vt_cputs, 130 .flush = remcons_vt_flush 132 .flush = remcons_vt_flush, 133 .key = remcons_vt_key 131 134 }; 132 135 … … 340 343 } 341 344 345 /** Creates new keyboard event from given char. 346 * 347 * @param type Event type (press / release). 348 * @param c Pressed character. 349 */ 350 static 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 342 365 static errno_t remcons_get_event(con_srv_t *srv, cons_event_t *event) 343 366 { 367 remcons_t *remcons = srv_to_remcons(srv); 344 368 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); 354 384 355 385 event->type = CEV_KEY; 356 event->ev.key = kevent; 386 event->ev.key = *tmp; 387 388 free(tmp); 357 389 358 390 return EOK; … … 551 583 } 552 584 585 static 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 553 597 /** Handle network connection. 554 598 * … … 567 611 remcons->enable_rgb = !no_ctl && !no_rgb; 568 612 remcons->user = user; 613 prodcons_initialize(&remcons->in_events); 569 614 570 615 if (remcons->enable_ctl) { -
uspace/srv/hid/remcons/remcons.h
rd31c3ea r6907f26 37 37 #define REMCONS_H_ 38 38 39 #include <adt/prodcons.h> 39 40 #include <stdbool.h> 40 41 #include <vt/vt100.h> … … 54 55 charfield_t *ubuf; /**< user buffer */ 55 56 bool curs_visible; /**< cursor is visible */ 57 58 /** Producer-consumer of kbd_event_t. */ 59 prodcons_t in_events; 56 60 } remcons_t; 57 61 -
uspace/srv/hid/remcons/user.c
rd31c3ea r6907f26 83 83 user->conn = conn; 84 84 user->service_id = (service_id_t) -1; 85 prodcons_initialize(&user->in_events);86 85 link_initialize(&user->link); 87 86 user->socket_buffer_len = 0; … … 211 210 } 212 211 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 216 217 */ 217 218 static errno_t telnet_user_recv_next_byte_locked(telnet_user_t *user, char *byte) … … 230 231 } 231 232 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 */ 238 static bool telnet_user_byte_avail(telnet_user_t *user) 239 { 240 return user->socket_buffer_len > user->socket_buffer_pos; 285 241 } 286 242 … … 303 259 } 304 260 305 /** Get next keyboard event.261 /** Receive data from telnet connection. 306 262 * 307 263 * @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 */ 269 errno_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 { 315 279 char next_byte = 0; 316 280 bool inside_telnet_command = false; … … 319 283 320 284 /* 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); 326 290 return rc; 327 291 } 328 292 uint8_t byte = (uint8_t) next_byte; 329 fibril_mutex_lock(&user->guard);330 293 331 294 /* Skip telnet commands. */ … … 345 308 next_byte = 0; 346 309 } 347 } 310 } while (next_byte == 0 && telnet_user_byte_avail(user)); 348 311 349 312 /* CR-LF conversions. */ … … 352 315 } 353 316 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); 371 325 return EOK; 372 326 } -
uspace/srv/hid/remcons/user.h
rd31c3ea r6907f26 37 37 #define TELNET_USER_H_ 38 38 39 #include <adt/prodcons.h>40 39 #include <fibril_synch.h> 41 40 #include <inet/tcp.h> … … 62 61 con_srvs_t srvs; 63 62 64 /** Producer-consumer of kbd_event_t. */65 prodcons_t in_events;66 63 link_t link; 67 64 char socket_buffer[BUFFER_SIZE];
Note:
See TracChangeset
for help on using the changeset viewer.