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