diff options
Diffstat (limited to 'rsnix/src/vt.rs')
| -rw-r--r-- | rsnix/src/vt.rs | 33 |
1 files changed, 26 insertions, 7 deletions
diff --git a/rsnix/src/vt.rs b/rsnix/src/vt.rs index 3b81d68..4db08fc 100644 --- a/rsnix/src/vt.rs +++ b/rsnix/src/vt.rs | |||
| @@ -485,20 +485,29 @@ pub fn clear_all() { | |||
| 485 | // --------------------------------------------------------------------------- | 485 | // --------------------------------------------------------------------------- |
| 486 | 486 | ||
| 487 | /// Blit every cell whose content differs from what the framebuffer shows, | 487 | /// Blit every cell whose content differs from what the framebuffer shows, |
| 488 | /// then draw the logical cursor (inverse video) on top. | 488 | /// then draw the logical cursor (inverse video) on top. The cursor's |
| 489 | /// inverse colours are mirrored into RENDERED so that pixel shifts | ||
| 490 | /// (scrolling) or full clears can never leave a stale inverse block that | ||
| 491 | /// the diff can't see (blank-vs-blank). | ||
| 489 | fn flush() { | 492 | fn flush() { |
| 490 | let rows = unsafe { ROWS }; | 493 | let rows = unsafe { ROWS }; |
| 491 | let cols = unsafe { COLS }; | 494 | let cols = unsafe { COLS }; |
| 492 | let n = rows * cols; | 495 | let n = rows * cols; |
| 496 | let cursor_visible = unsafe { CURSOR_VISIBLE }; | ||
| 497 | let (cr, cc) = unsafe { (CURSOR_R, CURSOR_C) }; | ||
| 493 | { | 498 | { |
| 494 | let cells = cells(); | 499 | let cells = cells(); |
| 495 | let rendered = rendered_cells(); | 500 | let rendered = rendered_cells(); |
| 496 | for i in 0..n { | 501 | for i in 0..n { |
| 502 | let row = i / cols; | ||
| 503 | let col = i % cols; | ||
| 504 | // The visible cursor cell is owned by the cursor pass below. | ||
| 505 | if cursor_visible && row == cr && col == cc { | ||
| 506 | continue; | ||
| 507 | } | ||
| 497 | let c = cells[i]; | 508 | let c = cells[i]; |
| 498 | let r = rendered[i]; | 509 | let r = rendered[i]; |
| 499 | if c != r { | 510 | if c != r { |
| 500 | let row = i / cols; | ||
| 501 | let col = i % cols; | ||
| 502 | let fg = PALETTE[c.fg as usize]; | 511 | let fg = PALETTE[c.fg as usize]; |
| 503 | let bg = PALETTE[c.bg as usize]; | 512 | let bg = PALETTE[c.bg as usize]; |
| 504 | gop::blit_glyph(col, row, c.ch, fg, bg); | 513 | gop::blit_glyph(col, row, c.ch, fg, bg); |
| @@ -510,20 +519,30 @@ fn flush() { | |||
| 510 | unsafe { | 519 | unsafe { |
| 511 | let (lr, lc) = LAST_CURSOR; | 520 | let (lr, lc) = LAST_CURSOR; |
| 512 | let moved = (lr, lc) != (CURSOR_R, CURSOR_C); | 521 | let moved = (lr, lc) != (CURSOR_R, CURSOR_C); |
| 513 | // Erase the previous cursor position (restore its normal colours). | 522 | // Erase the previous cursor position (restore its normal colours) |
| 523 | // and record it in RENDERED so the diff stays in sync. | ||
| 514 | if (moved || !CURSOR_VISIBLE) && lr < rows && lc < cols { | 524 | if (moved || !CURSOR_VISIBLE) && lr < rows && lc < cols { |
| 515 | let c = cells()[idx(lr, lc)]; | 525 | let i = idx(lr, lc); |
| 526 | let c = cells()[i]; | ||
| 516 | let fg = PALETTE[c.fg as usize]; | 527 | let fg = PALETTE[c.fg as usize]; |
| 517 | let bg = PALETTE[c.bg as usize]; | 528 | let bg = PALETTE[c.bg as usize]; |
| 518 | gop::blit_glyph(lc, lr, c.ch, fg, bg); | 529 | gop::blit_glyph(lc, lr, c.ch, fg, bg); |
| 530 | rendered_cells()[i] = c; | ||
| 519 | } | 531 | } |
| 520 | LAST_CURSOR = (CURSOR_R, CURSOR_C); | 532 | LAST_CURSOR = (CURSOR_R, CURSOR_C); |
| 521 | // Draw the cursor as an inverse-video cell. | 533 | // Draw the cursor as an inverse-video cell, mirroring the inverse |
| 534 | // colours into RENDERED (scrolling/clearing then repair it). | ||
| 522 | if CURSOR_VISIBLE && CURSOR_R < rows && CURSOR_C < cols { | 535 | if CURSOR_VISIBLE && CURSOR_R < rows && CURSOR_C < cols { |
| 523 | let c = cells()[idx(CURSOR_R, CURSOR_C)]; | 536 | let i = idx(CURSOR_R, CURSOR_C); |
| 537 | let c = cells()[i]; | ||
| 524 | let fg = PALETTE[c.fg as usize]; | 538 | let fg = PALETTE[c.fg as usize]; |
| 525 | let bg = PALETTE[c.bg as usize]; | 539 | let bg = PALETTE[c.bg as usize]; |
| 526 | gop::blit_glyph(CURSOR_C, CURSOR_R, c.ch, bg, fg); | 540 | gop::blit_glyph(CURSOR_C, CURSOR_R, c.ch, bg, fg); |
| 541 | rendered_cells()[i] = Cell { | ||
| 542 | ch: c.ch, | ||
| 543 | fg: c.bg, | ||
| 544 | bg: c.fg, | ||
| 545 | }; | ||
| 527 | } | 546 | } |
| 528 | } | 547 | } |
| 529 | } | 548 | } |
