Changes in uspace/srv/hid/console/console.c [28a5ebd:1a96db9] in mainline
- File:
-
- 1 edited
-
uspace/srv/hid/console/console.c (modified) (24 diffs)
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/hid/console/console.c
r28a5ebd r1a96db9 1 1 /* 2 * Copyright (c) 2025 Jiri Svoboda 2 3 * Copyright (c) 2011 Martin Decky 3 4 * All rights reserved. … … 36 37 #include <stdio.h> 37 38 #include <adt/prodcons.h> 39 #include <io/console.h> 38 40 #include <io/input.h> 39 41 #include <ipc/vfs.h> … … 62 64 typedef struct { 63 65 atomic_flag refcnt; /**< Connection reference count */ 64 prodcons_t input_pc; /**< Incoming keyboardevents */66 prodcons_t input_pc; /**< Incoming console events */ 65 67 66 68 /** … … 79 81 console_caps_t ccaps; /**< Console capabilities */ 80 82 83 sysarg_t ucols; /**< Number of columns in user buffer */ 84 sysarg_t urows; /**< Number of rows in user buffer */ 85 charfield_t *ubuf; /**< User buffer */ 86 81 87 chargrid_t *frontbuf; /**< Front buffer */ 82 88 frontbuf_handle_t fbid; /**< Front buffer handle */ … … 84 90 } console_t; 85 91 92 static loc_srv_t *console_srv; 93 86 94 /** Input server proxy */ 87 95 static input_t *input; … … 95 103 static sysarg_t rows; 96 104 105 /** Mouse pointer X coordinate */ 106 static int pointer_x; 107 /** Mouse pointer Y coordinate */ 108 static int pointer_y; 109 /** Character under mouse cursor */ 110 static charfield_t pointer_bg; 111 112 static int mouse_scale_x = 4; 113 static int mouse_scale_y = 8; 114 97 115 /** Array of data for virtual consoles */ 98 116 static console_t consoles[CONSOLE_COUNT]; … … 105 123 static errno_t input_ev_active(input_t *); 106 124 static errno_t input_ev_deactive(input_t *); 107 static errno_t input_ev_key(input_t *, kbd_event_type_t, keycode_t, keymod_t, char32_t); 108 static errno_t input_ev_move(input_t *, int, int); 109 static errno_t input_ev_abs_move(input_t *, unsigned, unsigned, unsigned, unsigned); 110 static errno_t input_ev_button(input_t *, int, int); 125 static errno_t input_ev_key(input_t *, unsigned, kbd_event_type_t, keycode_t, 126 keymod_t, char32_t); 127 static errno_t input_ev_move(input_t *, unsigned, int, int); 128 static errno_t input_ev_abs_move(input_t *, unsigned, unsigned, unsigned, 129 unsigned, unsigned); 130 static errno_t input_ev_button(input_t *, unsigned, int, int); 131 static errno_t input_ev_dclick(input_t *, unsigned, int); 111 132 112 133 static input_ev_ops_t input_ev_ops = { … … 116 137 .move = input_ev_move, 117 138 .abs_move = input_ev_abs_move, 118 .button = input_ev_button 139 .button = input_ev_button, 140 .dclick = input_ev_dclick 119 141 }; 120 142 … … 134 156 static void cons_set_rgb_color(con_srv_t *, pixel_t, pixel_t); 135 157 static void cons_set_cursor_visibility(con_srv_t *, bool); 158 static errno_t cons_set_caption(con_srv_t *, const char *); 136 159 static errno_t cons_get_event(con_srv_t *, cons_event_t *); 160 static errno_t cons_map(con_srv_t *, sysarg_t, sysarg_t, charfield_t **); 161 static void cons_unmap(con_srv_t *); 162 static void cons_buf_update(con_srv_t *, sysarg_t, sysarg_t, sysarg_t, 163 sysarg_t); 137 164 138 165 static con_ops_t con_ops = { … … 151 178 .set_rgb_color = cons_set_rgb_color, 152 179 .set_cursor_visibility = cons_set_cursor_visibility, 153 .get_event = cons_get_event 180 .set_caption = cons_set_caption, 181 .get_event = cons_get_event, 182 .map = cons_map, 183 .unmap = cons_unmap, 184 .update = cons_buf_update 154 185 }; 186 187 static void pointer_draw(void); 188 static void pointer_undraw(void); 155 189 156 190 static console_t *srv_to_console(con_srv_t *srv) … … 219 253 220 254 fibril_mutex_lock(&switch_mtx); 255 pointer_undraw(); 221 256 222 257 if (cons == active_console) { … … 227 262 active_console = cons; 228 263 264 pointer_draw(); 229 265 fibril_mutex_unlock(&switch_mtx); 230 266 231 267 cons_damage(cons); 268 } 269 270 /** Draw mouse pointer. */ 271 static void pointer_draw(void) 272 { 273 charfield_t *ch; 274 int col, row; 275 276 /* Downscale coordinates to text resolution */ 277 col = pointer_x / mouse_scale_x; 278 row = pointer_y / mouse_scale_y; 279 280 /* Make sure they are in range */ 281 if (col < 0 || row < 0 || col >= (int)cols || row >= (int)rows) 282 return; 283 284 ch = chargrid_charfield_at(active_console->frontbuf, col, row); 285 286 /* 287 * Store background attributes for undrawing the pointer. 288 * This is necessary as styles cannot be inverted with 289 * round trip (unlike RGB or INDEX) 290 */ 291 pointer_bg = *ch; 292 293 /* In general the color should be a one's complement of the background */ 294 if (ch->attrs.type == CHAR_ATTR_INDEX) { 295 ch->attrs.val.index.bgcolor ^= 0xf; 296 ch->attrs.val.index.fgcolor ^= 0xf; 297 } else if (ch->attrs.type == CHAR_ATTR_RGB) { 298 ch->attrs.val.rgb.fgcolor ^= 0xffffff; 299 ch->attrs.val.rgb.bgcolor ^= 0xffffff; 300 } else if (ch->attrs.type == CHAR_ATTR_STYLE) { 301 /* Don't have a proper inverse for each style */ 302 if (ch->attrs.val.style == STYLE_INVERTED) 303 ch->attrs.val.style = STYLE_NORMAL; 304 else 305 ch->attrs.val.style = STYLE_INVERTED; 306 } 307 308 /* Make sure the cell gets updated */ 309 ch->flags |= CHAR_FLAG_DIRTY; 310 } 311 312 /** Undraw mouse pointer. */ 313 static void pointer_undraw(void) 314 { 315 charfield_t *ch; 316 int col, row; 317 318 col = pointer_x / mouse_scale_x; 319 row = pointer_y / mouse_scale_y; 320 if (col < 0 || row < 0 || col >= (int)cols || row >= (int)rows) 321 return; 322 323 ch = chargrid_charfield_at(active_console->frontbuf, col, row); 324 *ch = pointer_bg; 325 ch->flags |= CHAR_FLAG_DIRTY; 326 } 327 328 /** Queue console event. 329 * 330 * @param cons Console 331 * @param ev Console event 332 */ 333 static void console_queue_cons_event(console_t *cons, cons_event_t *ev) 334 { 335 /* Got key press/release event */ 336 cons_qevent_t *event = 337 (cons_qevent_t *) malloc(sizeof(cons_qevent_t)); 338 if (event == NULL) 339 return; 340 341 event->ev = *ev; 342 link_initialize(&event->link); 343 344 prodcons_produce(&cons->input_pc, &event->link); 232 345 } 233 346 … … 249 362 } 250 363 251 static errno_t input_ev_key(input_t *input, kbd_event_type_t type, keycode_t key, 252 keymod_t mods, char32_t c) 253 { 364 static errno_t input_ev_key(input_t *input, unsigned kbd_id, 365 kbd_event_type_t type, keycode_t key, keymod_t mods, char32_t c) 366 { 367 cons_event_t event; 368 bool alt; 369 bool shift; 370 371 alt = (mods & KM_ALT) != 0 && (mods & (KM_CTRL | KM_SHIFT)) == 0; 372 shift = (mods & KM_SHIFT) != 0 && (mods & (KM_CTRL | KM_ALT)) == 0; 373 374 /* Switch console on Alt+Fn or Shift+Fn */ 254 375 if ((key >= KC_F1) && (key <= KC_F1 + CONSOLE_COUNT) && 255 ( (mods & KM_CTRL) == 0)) {376 (alt || shift)) { 256 377 cons_switch(key - KC_F1); 257 378 } else { 258 379 /* Got key press/release event */ 259 kbd_event_t *event = 260 (kbd_event_t *) malloc(sizeof(kbd_event_t)); 261 if (event == NULL) { 262 return ENOMEM; 263 } 264 265 link_initialize(&event->link); 266 event->type = type; 267 event->key = key; 268 event->mods = mods; 269 event->c = c; 270 271 prodcons_produce(&active_console->input_pc, 272 &event->link); 273 } 274 275 return EOK; 276 } 277 278 static errno_t input_ev_move(input_t *input, int dx, int dy) 279 { 280 return EOK; 281 } 282 283 static errno_t input_ev_abs_move(input_t *input, unsigned x, unsigned y, 284 unsigned max_x, unsigned max_y) 285 { 286 return EOK; 287 } 288 289 static errno_t input_ev_button(input_t *input, int bnum, int bpress) 290 { 380 event.type = CEV_KEY; 381 382 (void)kbd_id; 383 event.ev.key.type = type; 384 event.ev.key.key = key; 385 event.ev.key.mods = mods; 386 event.ev.key.c = c; 387 388 console_queue_cons_event(active_console, &event); 389 } 390 391 return EOK; 392 } 393 394 /** Update pointer position. 395 * 396 * @param new_x New X coordinate (in pixels) 397 * @param new_y New Y coordinate (in pixels) 398 */ 399 static void pointer_update(int new_x, int new_y) 400 { 401 bool upd_pointer; 402 403 /* Make sure coordinates are in range */ 404 405 if (new_x < 0) 406 new_x = 0; 407 if (new_x >= (int)cols * mouse_scale_x) 408 new_x = cols * mouse_scale_x - 1; 409 if (new_y < 0) 410 new_y = 0; 411 if (new_y >= (int)rows * mouse_scale_y) 412 new_y = rows * mouse_scale_y - 1; 413 414 /* Determine if pointer moved to a different character cell */ 415 upd_pointer = (new_x / mouse_scale_x != pointer_x / mouse_scale_x) || 416 (new_y / mouse_scale_y != pointer_y / mouse_scale_y); 417 418 if (upd_pointer) 419 pointer_undraw(); 420 421 /* Store new pointer position */ 422 pointer_x = new_x; 423 pointer_y = new_y; 424 425 if (upd_pointer) { 426 pointer_draw(); 427 cons_update(active_console); 428 } 429 } 430 431 static errno_t input_ev_move(input_t *input, unsigned pos_id, int dx, int dy) 432 { 433 (void) pos_id; 434 pointer_update(pointer_x + dx, pointer_y + dy); 435 return EOK; 436 } 437 438 static errno_t input_ev_abs_move(input_t *input, unsigned pos_id, unsigned x, 439 unsigned y, unsigned max_x, unsigned max_y) 440 { 441 (void)pos_id; 442 pointer_update(mouse_scale_x * cols * x / max_x, mouse_scale_y * rows * y / max_y); 443 return EOK; 444 } 445 446 static errno_t input_ev_button(input_t *input, unsigned pos_id, int bnum, 447 int bpress) 448 { 449 cons_event_t event; 450 451 (void)pos_id; 452 453 event.type = CEV_POS; 454 event.ev.pos.type = bpress ? POS_PRESS : POS_RELEASE; 455 event.ev.pos.btn_num = bnum; 456 event.ev.pos.hpos = pointer_x / mouse_scale_x; 457 event.ev.pos.vpos = pointer_y / mouse_scale_y; 458 459 console_queue_cons_event(active_console, &event); 460 return EOK; 461 } 462 463 static errno_t input_ev_dclick(input_t *input, unsigned pos_id, int bnum) 464 { 465 cons_event_t event; 466 467 (void)pos_id; 468 469 event.type = CEV_POS; 470 event.ev.pos.type = POS_DCLICK; 471 event.ev.pos.btn_num = bnum; 472 event.ev.pos.hpos = pointer_x / mouse_scale_x; 473 event.ev.pos.vpos = pointer_y / mouse_scale_y; 474 475 console_queue_cons_event(active_console, &event); 291 476 return EOK; 292 477 } … … 298 483 299 484 fibril_mutex_lock(&cons->mtx); 485 pointer_undraw(); 300 486 301 487 switch (ch) { … … 304 490 break; 305 491 case '\r': 492 updated = chargrid_cr(cons->frontbuf); 306 493 break; 307 494 case '\t': … … 315 502 } 316 503 504 pointer_draw(); 317 505 fibril_mutex_unlock(&cons->mtx); 318 506 … … 324 512 { 325 513 fibril_mutex_lock(&cons->mtx); 514 pointer_undraw(); 326 515 chargrid_set_cursor_visibility(cons->frontbuf, visible); 516 pointer_draw(); 327 517 fibril_mutex_unlock(&cons->mtx); 328 518 … … 367 557 if (pos < size) { 368 558 link_t *link = prodcons_consume(&cons->input_pc); 369 kbd_event_t *event = list_get_instance(link, kbd_event_t, link); 559 cons_qevent_t *qevent = list_get_instance(link, 560 cons_qevent_t, link); 561 cons_event_t *event = &qevent->ev; 370 562 371 563 /* Accept key presses of printable chars only. */ 372 if ((event->type == KEY_PRESS) && (event->c != 0)) { 373 char32_t tmp[2] = { event->c, 0 }; 564 if (event->type == CEV_KEY && event->ev.key.type == KEY_PRESS && 565 (event->ev.key.c != 0)) { 566 char32_t tmp[2] = { event->ev.key.c, 0 }; 374 567 wstr_to_str(cons->char_remains, UTF8_CHAR_BUFFER_SIZE, tmp); 375 568 cons->char_remains_len = str_size(cons->char_remains); 376 569 } 377 570 378 free( event);571 free(qevent); 379 572 } 380 573 } … … 408 601 409 602 fibril_mutex_lock(&cons->mtx); 603 pointer_undraw(); 410 604 chargrid_clear(cons->frontbuf); 605 pointer_draw(); 411 606 fibril_mutex_unlock(&cons->mtx); 412 607 … … 419 614 420 615 fibril_mutex_lock(&cons->mtx); 616 pointer_undraw(); 421 617 chargrid_set_cursor(cons->frontbuf, col, row); 618 pointer_draw(); 422 619 fibril_mutex_unlock(&cons->mtx); 423 620 … … 495 692 } 496 693 694 static errno_t cons_set_caption(con_srv_t *srv, const char *caption) 695 { 696 console_t *cons = srv_to_console(srv); 697 698 (void) cons; 699 (void) caption; 700 return EOK; 701 } 702 497 703 static errno_t cons_get_event(con_srv_t *srv, cons_event_t *event) 498 704 { 499 705 console_t *cons = srv_to_console(srv); 500 706 link_t *link = prodcons_consume(&cons->input_pc); 501 kbd_event_t *kevent = list_get_instance(link, kbd_event_t, link); 502 503 event->type = CEV_KEY; 504 event->ev.key = *kevent; 505 506 free(kevent); 507 return EOK; 707 cons_qevent_t *qevent = list_get_instance(link, cons_qevent_t, link); 708 709 *event = qevent->ev; 710 free(qevent); 711 return EOK; 712 } 713 714 /** Create shared buffer for efficient rendering. 715 * 716 * @param srv Console server 717 * @param cols Number of columns in buffer 718 * @param rows Number of rows in buffer 719 * @param rbuf Place to store pointer to new sharable buffer 720 * 721 * @return EOK on sucess or an error code 722 */ 723 static errno_t cons_map(con_srv_t *srv, sysarg_t cols, sysarg_t rows, 724 charfield_t **rbuf) 725 { 726 console_t *cons = srv_to_console(srv); 727 void *buf; 728 729 fibril_mutex_lock(&cons->mtx); 730 731 if (cons->ubuf != NULL) { 732 fibril_mutex_unlock(&cons->mtx); 733 return EBUSY; 734 } 735 736 buf = as_area_create(AS_AREA_ANY, cols * rows * sizeof(charfield_t), 737 AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE, AS_AREA_UNPAGED); 738 if (buf == AS_MAP_FAILED) { 739 fibril_mutex_unlock(&cons->mtx); 740 return ENOMEM; 741 } 742 743 cons->ucols = cols; 744 cons->urows = rows; 745 cons->ubuf = buf; 746 fibril_mutex_unlock(&cons->mtx); 747 748 *rbuf = buf; 749 return EOK; 750 } 751 752 /** Delete shared buffer. 753 * 754 * @param srv Console server 755 */ 756 static void cons_unmap(con_srv_t *srv) 757 { 758 console_t *cons = srv_to_console(srv); 759 void *buf; 760 761 fibril_mutex_lock(&cons->mtx); 762 763 buf = cons->ubuf; 764 cons->ubuf = NULL; 765 766 if (buf != NULL) 767 as_area_destroy(buf); 768 769 fibril_mutex_unlock(&cons->mtx); 770 } 771 772 /** Update area of console from shared buffer. 773 * 774 * @param srv Console server 775 * @param c0 Column coordinate of top-left corner (inclusive) 776 * @param r0 Row coordinate of top-left corner (inclusive) 777 * @param c1 Column coordinate of bottom-right corner (exclusive) 778 * @param r1 Row coordinate of bottom-right corner (exclusive) 779 */ 780 static void cons_buf_update(con_srv_t *srv, sysarg_t c0, sysarg_t r0, 781 sysarg_t c1, sysarg_t r1) 782 { 783 console_t *cons = srv_to_console(srv); 784 charfield_t *ch; 785 sysarg_t col, row; 786 787 fibril_mutex_lock(&cons->mtx); 788 789 if (cons->ubuf == NULL) { 790 fibril_mutex_unlock(&cons->mtx); 791 return; 792 } 793 794 /* Make sure we have meaningful coordinates, within bounds */ 795 796 if (c1 > cons->ucols) 797 c1 = cons->ucols; 798 if (c1 > cons->cols) 799 c1 = cons->cols; 800 if (c0 >= c1) { 801 fibril_mutex_unlock(&cons->mtx); 802 return; 803 } 804 if (r1 > cons->urows) 805 r1 = cons->urows; 806 if (r1 > cons->rows) 807 r1 = cons->rows; 808 if (r0 >= r1) { 809 fibril_mutex_unlock(&cons->mtx); 810 return; 811 } 812 813 /* Update front buffer from user buffer */ 814 815 pointer_undraw(); 816 817 for (row = r0; row < r1; row++) { 818 for (col = c0; col < c1; col++) { 819 ch = chargrid_charfield_at(cons->frontbuf, col, row); 820 *ch = cons->ubuf[row * cons->ucols + col]; 821 } 822 } 823 824 pointer_draw(); 825 fibril_mutex_unlock(&cons->mtx); 826 827 /* Update console */ 828 cons_update(cons); 508 829 } 509 830 … … 592 913 /* Register server */ 593 914 async_set_fallback_port_handler(client_connection, NULL); 594 rc = loc_server_register(NAME );915 rc = loc_server_register(NAME, &console_srv); 595 916 if (rc != EOK) { 596 917 printf("%s: Unable to register server (%s)\n", NAME, … … 642 963 snprintf(vc, LOC_NAME_MAXLEN, "%s/vc%zu", NAMESPACE, i); 643 964 644 if (loc_service_register(vc, &consoles[i].dsid) != EOK) { 965 if (loc_service_register(console_srv, vc, 966 fallback_port_id, &consoles[i].dsid) != EOK) { 645 967 printf("%s: Unable to register device %s\n", NAME, vc); 646 968 return false; … … 649 971 650 972 input_activate(input); 973 active = true; 974 cons_damage(active_console); 651 975 } 652 976
Note:
See TracChangeset
for help on using the changeset viewer.
