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