Changeset a35b458 in mainline for uspace/lib/gui/terminal.c
- Timestamp:
- 2018-03-02T20:10:49Z (7 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- f1380b7
- Parents:
- 3061bc1
- git-author:
- Jiří Zárevúcky <zarevucky.jiri@…> (2018-02-28 17:38:31)
- git-committer:
- Jiří Zárevúcky <zarevucky.jiri@…> (2018-03-02 20:10:49)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/gui/terminal.c
r3061bc1 ra35b458 118 118 [COLOR_YELLOW] = PIXEL(255, 240, 240, 0), 119 119 [COLOR_WHITE] = PIXEL(255, 240, 240, 240), 120 120 121 121 [COLOR_BLACK + 8] = PIXEL(255, 0, 0, 0), 122 122 [COLOR_BLUE + 8] = PIXEL(255, 0, 0, 255), … … 170 170 charfield_t *field = 171 171 chargrid_charfield_at(term->backbuf, col, row); 172 172 173 173 bool inverted = chargrid_cursor_at(term->backbuf, col, row); 174 174 175 175 sysarg_t bx = sx + (col * FONT_WIDTH); 176 176 sysarg_t by = sy + (row * FONT_SCANLINES); 177 177 178 178 pixel_t bgcolor = 0; 179 179 pixel_t fgcolor = 0; 180 180 181 181 if (inverted) 182 182 attrs_rgb(field->attrs, &fgcolor, &bgcolor); 183 183 else 184 184 attrs_rgb(field->attrs, &bgcolor, &fgcolor); 185 185 186 186 // FIXME: Glyph type should be actually uint32_t 187 187 // for full UTF-32 coverage. 188 188 189 189 uint16_t glyph = fb_font_glyph(field->ch, NULL); 190 190 191 191 for (unsigned int y = 0; y < FONT_SCANLINES; y++) { 192 192 pixel_t *dst = pixelmap_pixel_at( … … 207 207 { 208 208 sysarg_t top_row = chargrid_get_top_row(term->frontbuf); 209 209 210 210 if (term->top_row == top_row) 211 211 return false; 212 212 213 213 term->top_row = top_row; 214 214 215 215 for (sysarg_t row = 0; row < term->rows; row++) { 216 216 for (sysarg_t col = 0; col < term->cols; col++) { … … 220 220 chargrid_charfield_at(term->backbuf, col, row); 221 221 bool update = false; 222 222 223 223 if (front_field->ch != back_field->ch) { 224 224 back_field->ch = front_field->ch; 225 225 update = true; 226 226 } 227 227 228 228 if (!attrs_same(front_field->attrs, back_field->attrs)) { 229 229 back_field->attrs = front_field->attrs; 230 230 update = true; 231 231 } 232 232 233 233 front_field->flags &= ~CHAR_FLAG_DIRTY; 234 234 235 235 if (update) 236 236 term_update_char(term, surface, sx, sy, col, row); 237 237 } 238 238 } 239 239 240 240 return true; 241 241 } … … 245 245 { 246 246 bool damage = false; 247 247 248 248 sysarg_t front_col; 249 249 sysarg_t front_row; 250 250 chargrid_get_cursor(term->frontbuf, &front_col, &front_row); 251 251 252 252 sysarg_t back_col; 253 253 sysarg_t back_row; 254 254 chargrid_get_cursor(term->backbuf, &back_col, &back_row); 255 255 256 256 bool front_visibility = 257 257 chargrid_get_cursor_visibility(term->frontbuf) && … … 259 259 bool back_visibility = 260 260 chargrid_get_cursor_visibility(term->backbuf); 261 261 262 262 if (front_visibility != back_visibility) { 263 263 chargrid_set_cursor_visibility(term->backbuf, … … 266 266 damage = true; 267 267 } 268 268 269 269 if ((front_col != back_col) || (front_row != back_row)) { 270 270 chargrid_set_cursor(term->backbuf, front_col, front_row); … … 273 273 damage = true; 274 274 } 275 275 276 276 return damage; 277 277 } … … 280 280 { 281 281 fibril_mutex_lock(&term->mtx); 282 282 283 283 surface_t *surface = window_claim(term->widget.window); 284 284 if (!surface) { … … 287 287 return; 288 288 } 289 289 290 290 bool damage = false; 291 291 sysarg_t sx = term->widget.hpos; 292 292 sysarg_t sy = term->widget.vpos; 293 293 294 294 if (term_update_scroll(term, surface, sx, sy)) { 295 295 damage = true; … … 302 302 chargrid_charfield_at(term->backbuf, x, y); 303 303 bool update = false; 304 304 305 305 if ((front_field->flags & CHAR_FLAG_DIRTY) == 306 306 CHAR_FLAG_DIRTY) { … … 309 309 update = true; 310 310 } 311 311 312 312 if (!attrs_same(front_field->attrs, 313 313 back_field->attrs)) { … … 315 315 update = true; 316 316 } 317 317 318 318 front_field->flags &= ~CHAR_FLAG_DIRTY; 319 319 } 320 320 321 321 if (update) { 322 322 term_update_char(term, surface, sx, sy, x, y); … … 326 326 } 327 327 } 328 328 329 329 if (term_update_cursor(term, surface, sx, sy)) 330 330 damage = true; 331 331 332 332 window_yield(term->widget.window); 333 333 334 334 if (damage) 335 335 window_damage(term->widget.window); 336 336 337 337 fibril_mutex_unlock(&term->mtx); 338 338 } … … 341 341 { 342 342 fibril_mutex_lock(&term->mtx); 343 343 344 344 surface_t *surface = window_claim(term->widget.window); 345 345 if (!surface) { … … 348 348 return; 349 349 } 350 350 351 351 sysarg_t sx = term->widget.hpos; 352 352 sysarg_t sy = term->widget.vpos; 353 353 354 354 if (!term_update_scroll(term, surface, sx, sy)) { 355 355 for (sysarg_t y = 0; y < term->rows; y++) { … … 359 359 charfield_t *back_field = 360 360 chargrid_charfield_at(term->backbuf, x, y); 361 361 362 362 back_field->ch = front_field->ch; 363 363 back_field->attrs = front_field->attrs; 364 364 front_field->flags &= ~CHAR_FLAG_DIRTY; 365 365 366 366 term_update_char(term, surface, sx, sy, x, y); 367 367 } 368 368 } 369 369 } 370 370 371 371 term_update_cursor(term, surface, sx, sy); 372 372 373 373 window_yield(term->widget.window); 374 374 window_damage(term->widget.window); 375 375 376 376 fibril_mutex_unlock(&term->mtx); 377 377 } … … 392 392 uint8_t *bbuf = buf; 393 393 size_t pos = 0; 394 394 395 395 /* 396 396 * Read input from keyboard and copy it to the buffer. … … 403 403 bbuf[pos] = term->char_remains[0]; 404 404 pos++; 405 405 406 406 /* Unshift the array. */ 407 407 for (size_t i = 1; i < term->char_remains_len; i++) 408 408 term->char_remains[i - 1] = term->char_remains[i]; 409 409 410 410 term->char_remains_len--; 411 411 } 412 412 413 413 /* Still not enough? Then get another key from the queue. */ 414 414 if (pos < size) { 415 415 link_t *link = prodcons_consume(&term->input_pc); 416 416 cons_event_t *event = list_get_instance(link, cons_event_t, link); 417 417 418 418 /* Accept key presses of printable chars only. */ 419 419 if (event->type == CEV_KEY && event->ev.key.type == KEY_PRESS && … … 423 423 0 424 424 }; 425 425 426 426 wstr_to_str(term->char_remains, UTF8_CHAR_BUFFER_SIZE, tmp); 427 427 term->char_remains_len = str_size(term->char_remains); 428 428 } 429 429 430 430 free(event); 431 431 } 432 432 } 433 433 434 434 *nread = size; 435 435 return EOK; … … 439 439 { 440 440 sysarg_t updated = 0; 441 442 fibril_mutex_lock(&term->mtx); 443 441 442 fibril_mutex_lock(&term->mtx); 443 444 444 switch (ch) { 445 445 case '\n': … … 457 457 updated = chargrid_putchar(term->frontbuf, ch, true); 458 458 } 459 460 fibril_mutex_unlock(&term->mtx); 461 459 460 fibril_mutex_unlock(&term->mtx); 461 462 462 if (updated > 1) 463 463 term_update(term); … … 467 467 { 468 468 terminal_t *term = srv_to_terminal(srv); 469 469 470 470 size_t off = 0; 471 471 while (off < size) 472 472 term_write_char(term, str_decode(data, &off, size)); 473 473 474 474 *nwritten = size; 475 475 return EOK; … … 479 479 { 480 480 terminal_t *term = srv_to_terminal(srv); 481 481 482 482 term_update(term); 483 483 } … … 486 486 { 487 487 terminal_t *term = srv_to_terminal(srv); 488 488 489 489 fibril_mutex_lock(&term->mtx); 490 490 chargrid_clear(term->frontbuf); 491 491 fibril_mutex_unlock(&term->mtx); 492 492 493 493 term_update(term); 494 494 } … … 497 497 { 498 498 terminal_t *term = srv_to_terminal(srv); 499 499 500 500 fibril_mutex_lock(&term->mtx); 501 501 chargrid_set_cursor(term->frontbuf, col, row); 502 502 fibril_mutex_unlock(&term->mtx); 503 503 504 504 term_update(term); 505 505 } … … 508 508 { 509 509 terminal_t *term = srv_to_terminal(srv); 510 510 511 511 fibril_mutex_lock(&term->mtx); 512 512 chargrid_get_cursor(term->frontbuf, col, row); 513 513 fibril_mutex_unlock(&term->mtx); 514 514 515 515 return EOK; 516 516 } … … 519 519 { 520 520 terminal_t *term = srv_to_terminal(srv); 521 521 522 522 fibril_mutex_lock(&term->mtx); 523 523 *cols = term->cols; 524 524 *rows = term->rows; 525 525 fibril_mutex_unlock(&term->mtx); 526 526 527 527 return EOK; 528 528 } … … 532 532 (void) srv; 533 533 *caps = TERM_CAPS; 534 534 535 535 return EOK; 536 536 } … … 539 539 { 540 540 terminal_t *term = srv_to_terminal(srv); 541 541 542 542 fibril_mutex_lock(&term->mtx); 543 543 chargrid_set_style(term->frontbuf, style); … … 549 549 { 550 550 terminal_t *term = srv_to_terminal(srv); 551 551 552 552 fibril_mutex_lock(&term->mtx); 553 553 chargrid_set_color(term->frontbuf, bgcolor, fgcolor, attr); … … 559 559 { 560 560 terminal_t *term = srv_to_terminal(srv); 561 561 562 562 fibril_mutex_lock(&term->mtx); 563 563 chargrid_set_rgb_color(term->frontbuf, bgcolor, fgcolor); … … 568 568 { 569 569 terminal_t *term = srv_to_terminal(srv); 570 570 571 571 fibril_mutex_lock(&term->mtx); 572 572 chargrid_set_cursor_visibility(term->frontbuf, visible); 573 573 fibril_mutex_unlock(&term->mtx); 574 574 575 575 term_update(term); 576 576 } … … 581 581 link_t *link = prodcons_consume(&term->input_pc); 582 582 cons_event_t *ev = list_get_instance(link, cons_event_t, link); 583 583 584 584 *event = *ev; 585 585 free(ev); … … 591 591 list_remove(&term->link); 592 592 widget_deinit(&term->widget); 593 593 594 594 if (term->frontbuf) 595 595 chargrid_destroy(term->frontbuf); 596 596 597 597 if (term->backbuf) 598 598 chargrid_destroy(term->backbuf); … … 602 602 { 603 603 terminal_t *term = (terminal_t *) widget; 604 604 605 605 deinit_terminal(term); 606 606 free(term); … … 616 616 { 617 617 terminal_t *term = (terminal_t *) widget; 618 618 619 619 widget_modify(widget, hpos, vpos, width, height); 620 620 widget->width_ideal = width; 621 621 widget->height_ideal = height; 622 622 623 623 term_damage(term); 624 624 } … … 627 627 { 628 628 terminal_t *term = (terminal_t *) widget; 629 629 630 630 term_damage(term); 631 631 } … … 638 638 if (event == NULL) 639 639 return; 640 640 641 641 *event = *ev; 642 642 link_initialize(&event->link); 643 643 644 644 prodcons_produce(&term->input_pc, &event->link); 645 645 } … … 651 651 terminal_t *term = (terminal_t *) widget; 652 652 cons_event_t event; 653 653 654 654 event.type = CEV_KEY; 655 655 event.ev.key = kbd_event; 656 656 657 657 terminal_queue_cons_event(term, &event); 658 658 } … … 680 680 { 681 681 terminal_t *term = NULL; 682 682 683 683 list_foreach(terms, link, terminal_t, cur) { 684 684 if (cur->dsid == (service_id_t) IPC_GET_ARG2(*icall)) { … … 687 687 } 688 688 } 689 689 690 690 if (term == NULL) { 691 691 async_answer_0(iid, ENOENT); 692 692 return; 693 693 } 694 694 695 695 if (atomic_postinc(&term->refcnt) == 0) 696 696 chargrid_set_cursor_visibility(term->frontbuf, true); 697 697 698 698 con_conn(iid, icall, &term->srvs); 699 699 } … … 703 703 { 704 704 widget_init(&term->widget, parent, data); 705 705 706 706 link_initialize(&term->link); 707 707 fibril_mutex_initialize(&term->mtx); 708 708 atomic_set(&term->refcnt, 0); 709 709 710 710 prodcons_initialize(&term->input_pc); 711 711 term->char_remains_len = 0; 712 712 713 713 term->widget.width = width; 714 714 term->widget.height = height; 715 715 term->widget.width_ideal = width; 716 716 term->widget.height_ideal = height; 717 717 718 718 term->widget.destroy = terminal_destroy; 719 719 term->widget.reconfigure = terminal_reconfigure; … … 722 722 term->widget.handle_keyboard_event = terminal_handle_keyboard_event; 723 723 term->widget.handle_position_event = terminal_handle_position_event; 724 724 725 725 term->cols = width / FONT_WIDTH; 726 726 term->rows = height / FONT_SCANLINES; 727 727 728 728 term->frontbuf = NULL; 729 729 term->backbuf = NULL; 730 730 731 731 term->frontbuf = chargrid_create(term->cols, term->rows, 732 732 CHARGRID_FLAG_NONE); … … 735 735 return false; 736 736 } 737 737 738 738 term->backbuf = chargrid_create(term->cols, term->rows, 739 739 CHARGRID_FLAG_NONE); … … 742 742 return false; 743 743 } 744 744 745 745 chargrid_clear(term->frontbuf); 746 746 chargrid_clear(term->backbuf); 747 747 term->top_row = 0; 748 748 749 749 async_set_fallback_port_handler(term_connection, NULL); 750 750 con_srvs_init(&term->srvs); 751 751 term->srvs.ops = &con_ops; 752 752 term->srvs.sarg = term; 753 753 754 754 errno_t rc = loc_server_register(NAME); 755 755 if (rc != EOK) { … … 757 757 return false; 758 758 } 759 759 760 760 char vc[LOC_NAME_MAXLEN + 1]; 761 761 snprintf(vc, LOC_NAME_MAXLEN, "%s/%" PRIu64, NAMESPACE, 762 762 task_get_id()); 763 763 764 764 rc = loc_service_register(vc, &term->dsid); 765 765 if (rc != EOK) { … … 767 767 return false; 768 768 } 769 769 770 770 list_append(&term->link, &terms); 771 771 getterm(vc, "/app/bdsh"); 772 772 773 773 return true; 774 774 } … … 780 780 if (!term) 781 781 return NULL; 782 782 783 783 bool ret = init_terminal(term, parent, data, width, height); 784 784 if (!ret) { … … 786 786 return NULL; 787 787 } 788 788 789 789 return term; 790 790 }
Note:
See TracChangeset
for help on using the changeset viewer.