fix(v4): nothing of a session left on screen after logout

From the fresh review of the stick's increment 1 (With fixes):
- Critical: after logout Zuse's last screen, her prompt included, could be
  drawn back on a headless machine. The logout clear (ESC[2J) blanked the
  pixels only: Alt+TAB, still read while headless, redrew the terminal
  from its saved text; and if she had Alt+TABbed to the graphics view
  before the pull, the clear did nothing and her session stayed on screen
  (and the console did not draw at her next login). Now vt100_reset()
  forgets everything the terminal has shown -- the on-screen text, the
  scrollback and their boot snapshots -- makes it visible again and fills
  the screen; and Alt+TAB does nothing while the screen is off (v3's never
  is, so v3 is unchanged).
- Important: an EMERGENCY_CONSOLE_ENABLED build no longer clears the screen
  when Zuse's drive is pulled: its console goes on running.

Red: alttab_after_logout 183308 (4515 lit), alttab_before_pull 183529
(4539 lit; the console not redrawn), emergency_pull 183759 (0 lit).
Green: 184115, 184328, 184552; regression 184805-185956 (screens,
keyboard, hotplug, emergency, v3 typed by keyboard) all pass.
Accepted: 190111, 190312, 190710, POST 538/538, dict_hash
0xfec8c47cfc6f437f; test-32, 39 modules, 0 failures.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
rajames
2026-10-26 19:14:22 -04:00
co-authored by Claude Opus 5.5
parent cab0ffb487
commit a78cc56c31
36 changed files with 11376 additions and 4 deletions
+3 -1
View File
@@ -102,7 +102,9 @@ void console_fb_enable_ttf(void);
* (docs/v4.0.0/STICK.md 2). The serial line always has everything. */
void console_fb_mirror(int on);
/* Erase the screen and put the cursor home (when the framebuffer is up). */
/* Erase the screen and forget everything the terminal has shown -- the
* on-screen text and the scrollback, so nothing can be drawn back -- and
* leave the terminal visible, cursor home (when the framebuffer is up). */
void console_fb_clear(void);
/**
+5
View File
@@ -110,6 +110,11 @@ void vt100_puts(const char *s);
*/
void vt100_toggle_graphics(void);
/* Forget everything the terminal has shown: the screen filled with the
* background, the terminal visible, the on-screen text, the scrollback and
* the boot-mode snapshot emptied, the cursor home. */
void vt100_reset(void);
/**
* Draw a solid block cursor at the terminal's current position. Static,
* not blinking. Idempotent -- safe to call after every keystroke, since
+5 -2
View File
@@ -262,8 +262,9 @@ void console_fb_mirror(int on) { g_fb_mirror = on ? 1 : 0; }
void console_fb_clear(void)
{
if (fb_is_available()) vt100_puts("\x1b[2J\x1b[H");
if (fb_is_available()) vt100_reset();
}
static uint64_t g_console_tx_count; /* monotonic console_putc() counter (BSS) */
void console_set_vm_name(const char *name) {
@@ -487,7 +488,9 @@ void console_fb_scroll_fwd(uint32_t n)
void console_fb_toggle_graphics(void)
{
if (fb_is_available()) {
/* Not while the screen is off (the v4 boot, headless): Alt+TAB would
* draw the terminal back (fixed 2026-10-26). v3's is always on. */
if (fb_mirrored()) {
vt100_toggle_graphics();
}
}
+33
View File
@@ -631,6 +631,39 @@ static void scrollback_redraw(void)
* reuse scrollback_redraw() to repaint the terminal's current on-screen
* content from that untouched logical state -- restored exactly as it
* logically stood, not merely as it last looked on screen. */
/* Everything the terminal has shown, forgotten: the screen filled with the
* background, the terminal visible again (out of the graphics view), and
* the on-screen text, the scrollback and the boot-mode snapshot of both
* emptied, so that nothing can be drawn back -- by Alt+TAB's redraw or by
* scrolling. The v4 boot's logout (docs/v4.0.0/STICK.md 2: nothing of a
* session is left on the screen; fixed 2026-10-26, the stick's increment 1
* final review: ESC[2J cleared the pixels only, and Alt+TAB drew her
* session back from g_shadow). */
void vt100_reset(void)
{
uint32_t r, c;
if (!g_vt.initialized) return;
g_terminal_visible = 1;
if (g_shadow) {
for (r = 0; r < g_vt.rows; r++) {
char *row = g_shadow + (size_t)r * g_line_stride;
for (c = 0; c < g_vt.cols; c++) row[c] = ' ';
row[g_vt.cols] = '\0';
}
}
g_ring_count = 0;
g_ring_head = 0;
g_scroll_offset = 0;
g_boot_ring_count = 0;
g_boot_rows = 0;
g_vt.cx = g_vt.cy = 0;
g_vt.saved_cx = g_vt.saved_cy = 0;
reset_attrs();
reset_parser();
fb_fill_rect(0, 0, fb_width(), fb_height(), g_vt.def_bg);
}
void vt100_toggle_graphics(void)
{
if (!g_ttf_ready || g_glyph_mode != VT_GLYPH_TTF) return;
+5 -1
View File
@@ -140,9 +140,13 @@ static void sk_v4_drive_left(blkio_dev_t *dev)
if (dev != g_zuse_dev) return;
g_zuse_session = 0;
g_zuse_dev = (struct blkio_dev *)0;
/* nothing of her session is left on the screen; it is dark again */
/* nothing of her session is left on the screen; it is dark again --
* except in a build with EMERGENCY_CONSOLE_ENABLED, whose console needs
* no login and goes on running (the stick's increment 1 final review) */
#if !EMERGENCY_CONSOLE_ENABLED
console_fb_clear();
console_fb_mirror(0);
#endif
console_println("Zuse: session ended -- reattach to re-authenticate");
}