Changes in uspace/srv/hid/console/console.c [28a5ebd:5d1ff11] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/hid/console/console.c
r28a5ebd r5d1ff11 1 1 /* 2 * Copyright (c) 2021 Jiri Svoboda 2 3 * Copyright (c) 2011 Martin Decky 3 4 * All rights reserved. … … 62 63 typedef struct { 63 64 atomic_flag refcnt; /**< Connection reference count */ 64 prodcons_t input_pc; /**< Incoming keyboardevents */65 prodcons_t input_pc; /**< Incoming console events */ 65 66 66 67 /** … … 79 80 console_caps_t ccaps; /**< Console capabilities */ 80 81 82 sysarg_t ucols; /**< Number of columns in user buffer */ 83 sysarg_t urows; /**< Number of rows in user buffer */ 84 charfield_t *ubuf; /**< User buffer */ 85 81 86 chargrid_t *frontbuf; /**< Front buffer */ 82 87 frontbuf_handle_t fbid; /**< Front buffer handle */ … … 94 99 static sysarg_t cols; 95 100 static sysarg_t rows; 101 102 /** Mouse pointer X coordinate */ 103 static int pointer_x; 104 /** Mouse pointer Y coordinate */ 105 static int pointer_y; 106 /** Character under mouse cursor */ 107 static charfield_t pointer_bg; 108 109 static int mouse_scale_x = 4; 110 static int mouse_scale_y = 8; 96 111 97 112 /** Array of data for virtual consoles */ … … 135 150 static void cons_set_cursor_visibility(con_srv_t *, bool); 136 151 static errno_t cons_get_event(con_srv_t *, cons_event_t *); 152 static errno_t cons_map(con_srv_t *, sysarg_t, sysarg_t, charfield_t **); 153 static void cons_unmap(con_srv_t *); 154 static void cons_buf_update(con_srv_t *, sysarg_t, sysarg_t, sysarg_t, 155 sysarg_t); 137 156 138 157 static con_ops_t con_ops = { … … 151 170 .set_rgb_color = cons_set_rgb_color, 152 171 .set_cursor_visibility = cons_set_cursor_visibility, 153 .get_event = cons_get_event 172 .get_event = cons_get_event, 173 .map = cons_map, 174 .unmap = cons_unmap, 175 .update = cons_buf_update 154 176 }; 177 178 static void pointer_draw(void); 179 static void pointer_undraw(void); 155 180 156 181 static console_t *srv_to_console(con_srv_t *srv) … … 219 244 220 245 fibril_mutex_lock(&switch_mtx); 246 pointer_undraw(); 221 247 222 248 if (cons == active_console) { … … 227 253 active_console = cons; 228 254 255 pointer_draw(); 229 256 fibril_mutex_unlock(&switch_mtx); 230 257 231 258 cons_damage(cons); 259 } 260 261 /** Draw mouse pointer. */ 262 static void pointer_draw(void) 263 { 264 charfield_t *ch; 265 int col, row; 266 267 /* Downscale coordinates to text resolution */ 268 col = pointer_x / mouse_scale_x; 269 row = pointer_y / mouse_scale_y; 270 271 /* Make sure they are in range */ 272 if (col < 0 || row < 0 || col >= (int)cols || row >= (int)rows) 273 return; 274 275 ch = chargrid_charfield_at(active_console->frontbuf, col, row); 276 277 /* 278 * Store background attributes for undrawing the pointer. 279 * This is necessary as styles cannot be inverted with 280 * round trip (unlike RGB or INDEX) 281 */ 282 pointer_bg = *ch; 283 284 /* In general the color should be a one's complement of the background */ 285 if (ch->attrs.type == CHAR_ATTR_INDEX) { 286 ch->attrs.val.index.bgcolor ^= 0xf; 287 ch->attrs.val.index.fgcolor ^= 0xf; 288 } else if (ch->attrs.type == CHAR_ATTR_RGB) { 289 ch->attrs.val.rgb.fgcolor ^= 0xffffff; 290 ch->attrs.val.rgb.bgcolor ^= 0xffffff; 291 } else if (ch->attrs.type == CHAR_ATTR_STYLE) { 292 /* Don't have a proper inverse for each style */ 293 if (ch->attrs.val.style == STYLE_INVERTED) 294 ch->attrs.val.style = STYLE_NORMAL; 295 else 296 ch->attrs.val.style = STYLE_INVERTED; 297 } 298 299 /* Make sure the cell gets updated */ 300 ch->flags |= CHAR_FLAG_DIRTY; 301 } 302 303 /** Undraw mouse pointer. */ 304 static void pointer_undraw(void) 305 { 306 charfield_t *ch; 307 int col, row; 308 309 col = pointer_x / mouse_scale_x; 310 row = pointer_y / mouse_scale_y; 311 if (col < 0 || row < 0 || col >= (int)cols || row >= (int)rows) 312 return; 313 314 ch = chargrid_charfield_at(active_console->frontbuf, col, row); 315 *ch = pointer_bg; 316 ch->flags |= CHAR_FLAG_DIRTY; 317 } 318 319 /** Queue console event. 320 * 321 * @param cons Console 322 * @param ev Console event 323 */ 324 static void console_queue_cons_event(console_t *cons, cons_event_t *ev) 325 { 326 /* Got key press/release event */ 327 cons_event_t *event = 328 (cons_event_t *) malloc(sizeof(cons_event_t)); 329 if (event == NULL) 330 return; 331 332 *event = *ev; 333 link_initialize(&event->link); 334 335 prodcons_produce(&cons->input_pc, &event->link); 232 336 } 233 337 … … 252 356 keymod_t mods, char32_t c) 253 357 { 358 cons_event_t event; 359 254 360 if ((key >= KC_F1) && (key <= KC_F1 + CONSOLE_COUNT) && 255 361 ((mods & KM_CTRL) == 0)) { … … 257 363 } else { 258 364 /* 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; 365 event.type = CEV_KEY; 366 367 event.ev.key.type = type; 368 event.ev.key.key = key; 369 event.ev.key.mods = mods; 370 event.ev.key.c = c; 371 372 console_queue_cons_event(active_console, &event); 373 } 374 375 return EOK; 376 } 377 378 /** Update pointer position. 379 * 380 * @param new_x New X coordinate (in pixels) 381 * @param new_y New Y coordinate (in pixels) 382 */ 383 static void pointer_update(int new_x, int new_y) 384 { 385 bool upd_pointer; 386 387 /* Make sure coordinates are in range */ 388 389 if (new_x < 0) 390 new_x = 0; 391 if (new_x >= (int)cols * mouse_scale_x) 392 new_x = cols * mouse_scale_x - 1; 393 if (new_y < 0) 394 new_y = 0; 395 if (new_y >= (int)rows * mouse_scale_y) 396 new_y = rows * mouse_scale_y - 1; 397 398 /* Determine if pointer moved to a different character cell */ 399 upd_pointer = (new_x / mouse_scale_x != pointer_x / mouse_scale_x) || 400 (new_y / mouse_scale_y != pointer_y / mouse_scale_y); 401 402 if (upd_pointer) 403 pointer_undraw(); 404 405 /* Store new pointer position */ 406 pointer_x = new_x; 407 pointer_y = new_y; 408 409 if (upd_pointer) { 410 pointer_draw(); 411 cons_update(active_console); 412 } 276 413 } 277 414 278 415 static errno_t input_ev_move(input_t *input, int dx, int dy) 279 416 { 417 pointer_update(pointer_x + dx, pointer_y + dy); 280 418 return EOK; 281 419 } … … 284 422 unsigned max_x, unsigned max_y) 285 423 { 424 pointer_update(mouse_scale_x * cols * x / max_x, mouse_scale_y * rows * y / max_y); 286 425 return EOK; 287 426 } … … 289 428 static errno_t input_ev_button(input_t *input, int bnum, int bpress) 290 429 { 430 cons_event_t event; 431 432 event.type = CEV_POS; 433 event.ev.pos.type = bpress ? POS_PRESS : POS_RELEASE; 434 event.ev.pos.btn_num = bnum; 435 event.ev.pos.hpos = pointer_x / mouse_scale_x; 436 event.ev.pos.vpos = pointer_y / mouse_scale_y; 437 438 console_queue_cons_event(active_console, &event); 291 439 return EOK; 292 440 } … … 298 446 299 447 fibril_mutex_lock(&cons->mtx); 448 pointer_undraw(); 300 449 301 450 switch (ch) { … … 315 464 } 316 465 466 pointer_draw(); 317 467 fibril_mutex_unlock(&cons->mtx); 318 468 … … 324 474 { 325 475 fibril_mutex_lock(&cons->mtx); 476 pointer_undraw(); 326 477 chargrid_set_cursor_visibility(cons->frontbuf, visible); 478 pointer_draw(); 327 479 fibril_mutex_unlock(&cons->mtx); 328 480 … … 367 519 if (pos < size) { 368 520 link_t *link = prodcons_consume(&cons->input_pc); 369 kbd_event_t *event = list_get_instance(link, kbd_event_t, link); 521 cons_event_t *event = list_get_instance(link, 522 cons_event_t, link); 370 523 371 524 /* Accept key presses of printable chars only. */ 372 if ((event->type == KEY_PRESS) && (event->c != 0)) { 373 char32_t tmp[2] = { event->c, 0 }; 525 if (event->type == CEV_KEY && event->ev.key.type == KEY_PRESS && 526 (event->ev.key.c != 0)) { 527 char32_t tmp[2] = { event->ev.key.c, 0 }; 374 528 wstr_to_str(cons->char_remains, UTF8_CHAR_BUFFER_SIZE, tmp); 375 529 cons->char_remains_len = str_size(cons->char_remains); … … 408 562 409 563 fibril_mutex_lock(&cons->mtx); 564 pointer_undraw(); 410 565 chargrid_clear(cons->frontbuf); 566 pointer_draw(); 411 567 fibril_mutex_unlock(&cons->mtx); 412 568 … … 419 575 420 576 fibril_mutex_lock(&cons->mtx); 577 pointer_undraw(); 421 578 chargrid_set_cursor(cons->frontbuf, col, row); 579 pointer_draw(); 422 580 fibril_mutex_unlock(&cons->mtx); 423 581 … … 499 657 console_t *cons = srv_to_console(srv); 500 658 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; 659 cons_event_t *cevent = list_get_instance(link, cons_event_t, link); 660 661 *event = *cevent; 662 free(cevent); 663 return EOK; 664 } 665 666 /** Create shared buffer for efficient rendering. 667 * 668 * @param srv Console server 669 * @param cols Number of columns in buffer 670 * @param rows Number of rows in buffer 671 * @param rbuf Place to store pointer to new sharable buffer 672 * 673 * @return EOK on sucess or an error code 674 */ 675 static errno_t cons_map(con_srv_t *srv, sysarg_t cols, sysarg_t rows, 676 charfield_t **rbuf) 677 { 678 console_t *cons = srv_to_console(srv); 679 void *buf; 680 681 fibril_mutex_lock(&cons->mtx); 682 683 if (cons->ubuf != NULL) { 684 fibril_mutex_unlock(&cons->mtx); 685 return EBUSY; 686 } 687 688 buf = as_area_create(AS_AREA_ANY, cols * rows * sizeof(charfield_t), 689 AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE, AS_AREA_UNPAGED); 690 if (buf == AS_MAP_FAILED) { 691 fibril_mutex_unlock(&cons->mtx); 692 return ENOMEM; 693 } 694 695 cons->ucols = cols; 696 cons->urows = rows; 697 cons->ubuf = buf; 698 fibril_mutex_unlock(&cons->mtx); 699 700 *rbuf = buf; 701 return EOK; 702 } 703 704 /** Delete shared buffer. 705 * 706 * @param srv Console server 707 */ 708 static void cons_unmap(con_srv_t *srv) 709 { 710 console_t *cons = srv_to_console(srv); 711 void *buf; 712 713 fibril_mutex_lock(&cons->mtx); 714 715 buf = cons->ubuf; 716 cons->ubuf = NULL; 717 718 if (buf != NULL) 719 as_area_destroy(buf); 720 721 fibril_mutex_unlock(&cons->mtx); 722 } 723 724 /** Update area of console from shared buffer. 725 * 726 * @param srv Console server 727 * @param c0 Column coordinate of top-left corner (inclusive) 728 * @param r0 Row coordinate of top-left corner (inclusive) 729 * @param c1 Column coordinate of bottom-right corner (exclusive) 730 * @param r1 Row coordinate of bottom-right corner (exclusive) 731 */ 732 static void cons_buf_update(con_srv_t *srv, sysarg_t c0, sysarg_t r0, 733 sysarg_t c1, sysarg_t r1) 734 { 735 console_t *cons = srv_to_console(srv); 736 charfield_t *ch; 737 sysarg_t col, row; 738 739 fibril_mutex_lock(&cons->mtx); 740 741 if (cons->ubuf == NULL) { 742 fibril_mutex_unlock(&cons->mtx); 743 return; 744 } 745 746 /* Make sure we have meaningful coordinates, within bounds */ 747 748 if (c1 > cons->ucols) 749 c1 = cons->ucols; 750 if (c1 > cons->cols) 751 c1 = cons->cols; 752 if (c0 >= c1) { 753 fibril_mutex_unlock(&cons->mtx); 754 return; 755 } 756 if (r1 > cons->urows) 757 r1 = cons->urows; 758 if (r1 > cons->rows) 759 r1 = cons->rows; 760 if (r0 >= r1) { 761 fibril_mutex_unlock(&cons->mtx); 762 return; 763 } 764 765 /* Update front buffer from user buffer */ 766 767 pointer_undraw(); 768 769 for (row = r0; row < r1; row++) { 770 for (col = c0; col < c1; col++) { 771 ch = chargrid_charfield_at(cons->frontbuf, col, row); 772 *ch = cons->ubuf[row * cons->ucols + col]; 773 } 774 } 775 776 pointer_draw(); 777 fibril_mutex_unlock(&cons->mtx); 778 779 /* Update console */ 780 cons_update(cons); 508 781 } 509 782 … … 649 922 650 923 input_activate(input); 924 active = true; 925 cons_damage(active_console); 651 926 } 652 927
Note:
See TracChangeset
for help on using the changeset viewer.