psogm: fit the report on an 800x600 screen
At 800x600 with the 21-pixel console cell there was not room for the logo, the facts and the call chain above the three closing lines. The chain ran into the footer, the footer was drawn over it, and what remained was the tail of a trace line after "asks more." -- the "0x5d" in the photo -- with the tops of "Call chain" underlining the line above. The layout is measured first now; the top margin gives way, then the logo, and the chain stops above the footer. Text in the rows the QR card shares stops short of it rather than running underneath. The screen is flushed unconditionally: the CPU that panicked may have stopped another halfway through a flush. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01S1giNvrHTrPMPw7V6x1kQ4
This commit is contained in:
parent
60d06658f0
commit
956d8de5d1
1 changed files with 58 additions and 14 deletions
|
|
@ -297,6 +297,30 @@ build_qr_payload(char *buf, int cap, char *reason, addr_t *pcs, int npcs)
|
|||
// stopped.
|
||||
static struct qr panic_qr;
|
||||
|
||||
// Where the card and its caption are, once drawn: the text column must stop
|
||||
// short of it on the rows they share. The reason and the call chain used to
|
||||
// run straight underneath it.
|
||||
static int qr_x0 = -1, qr_y0, qr_y1;
|
||||
|
||||
static void
|
||||
text_at(int x, int y, const char *s, uint32 color)
|
||||
{
|
||||
char buf[128];
|
||||
int n = 0, cap = sizeof(buf) - 1;
|
||||
|
||||
if (qr_x0 >= 0 && y + gfx_char_h() > qr_y0 && y < qr_y1) {
|
||||
int fit = (qr_x0 - gfx_char_w() - x) / gfx_char_w();
|
||||
if (fit < cap)
|
||||
cap = fit < 0 ? 0 : fit;
|
||||
}
|
||||
while (s[n] && n < cap) {
|
||||
buf[n] = s[n];
|
||||
n++;
|
||||
}
|
||||
buf[n] = 0;
|
||||
gfx_text_at(x, y, buf, color);
|
||||
}
|
||||
|
||||
// Returns the width used, so the text column knows what it may not overlap.
|
||||
static int
|
||||
draw_qr_panel(int sw, int sh, int ch, char *reason, addr_t *pcs, int npcs)
|
||||
|
|
@ -332,6 +356,9 @@ draw_qr_panel(int sw, int sh, int ch, char *reason, addr_t *pcs, int npcs)
|
|||
|
||||
gfx_text_at(x0, y0 + card + ch, "Scan for a text copy", PSOGM_DIM);
|
||||
gfx_text_at(x0, y0 + card + ch * 2 + 2, "of this report.", PSOGM_DIM);
|
||||
qr_x0 = x0;
|
||||
qr_y0 = y0;
|
||||
qr_y1 = y0 + card + ch * 3 + 2;
|
||||
|
||||
return card + sw / 24;
|
||||
}
|
||||
|
|
@ -388,6 +415,22 @@ paint(char *reason, addr_t *pcs, int npcs)
|
|||
if (left > 110) left = 110;
|
||||
int y = sh / 8;
|
||||
|
||||
// Everything above the three closing lines has to fit above them. At
|
||||
// 800x600 with a 21-pixel cell it did not: the call chain ran down into the
|
||||
// footer, the footer was drawn over it, and what showed was the tail of a
|
||||
// trace line poking out past the end of a sentence ("asks more.0x5d") with
|
||||
// the tops of "Call chain" underlining the line above. So the layout is
|
||||
// measured first -- the text, and room for two frames of the chain -- and
|
||||
// what gives way is the margin, then the logo. Never the report.
|
||||
int foot = sh - ch * 4 - ch / 2;
|
||||
int body = (ch + ch / 2) + ch * 2 + ch + nfields * (ch + 2) +
|
||||
ch + (ch + 2) + ch * 2;
|
||||
int logo = 1;
|
||||
if (y + LOGO_H + ch * 2 + body > foot)
|
||||
y = ch;
|
||||
if (y + LOGO_H + ch * 2 + body > foot)
|
||||
logo = 0;
|
||||
|
||||
// Shift, the system's own mark, from the same include/logo.h the loader
|
||||
// splash and the boot console draw. It replaces Guru, a chamfered face that
|
||||
// lived only here and was drawn from primitives a few lines up this file.
|
||||
|
|
@ -404,15 +447,17 @@ paint(char *reason, addr_t *pcs, int npcs)
|
|||
// A fixed 128 px rather than scaled: the mask is 128x128 and there is no
|
||||
// resampler here. The face was scalable and that bought nothing -- it was
|
||||
// drawn at one size.
|
||||
if (logo) {
|
||||
gfx_draw_logo(left, y, PSOGM_FG, PSOGM_BG);
|
||||
y += LOGO_H + ch * 2;
|
||||
}
|
||||
|
||||
// Left-aligned, not centred. Centred text reads as a poster; this is a
|
||||
// report, and a report is read down the left edge.
|
||||
gfx_text_at(left, y, "SchOS ran into a problem and needs to restart.",
|
||||
text_at(left, y, "SchOS ran into a problem and needs to restart.",
|
||||
PSOGM_FG);
|
||||
y += ch + ch / 2;
|
||||
gfx_text_at(left, y, "Nothing on your disks was touched by this.",
|
||||
text_at(left, y, "Nothing on your disks was touched by this.",
|
||||
PSOGM_DIM);
|
||||
|
||||
// A rule in the boot splash's accent, the same width as the one under the
|
||||
|
|
@ -428,22 +473,20 @@ paint(char *reason, addr_t *pcs, int npcs)
|
|||
// Facts: quiet labels down the left, bright values in a second column.
|
||||
int vx = left + 14 * cw;
|
||||
for (int i = 0; i < nfields; i++) {
|
||||
gfx_text_at(left, y, fields[i].label, PSOGM_DIM);
|
||||
gfx_text_at(vx, y, fields[i].value, PSOGM_FG);
|
||||
text_at(left, y, fields[i].label, PSOGM_DIM);
|
||||
text_at(vx, y, fields[i].value, PSOGM_FG);
|
||||
y += ch + 2;
|
||||
}
|
||||
|
||||
y += ch;
|
||||
gfx_text_at(left, y, "Call chain", PSOGM_DIM);
|
||||
text_at(left, y, "Call chain", PSOGM_DIM);
|
||||
y += ch + 2;
|
||||
|
||||
for (int i = 0; i < npcs && pcs[i]; i++) {
|
||||
for (int i = 0; i < npcs && pcs[i] && y + ch <= foot; i++) {
|
||||
char line[48];
|
||||
trace_line(line, sizeof(line), i, pcs[i]);
|
||||
gfx_text_at(vx - 3 * cw, y, line, PSOGM_FG);
|
||||
text_at(vx - 3 * cw, y, line, PSOGM_FG);
|
||||
y += ch;
|
||||
if (y > sh - ch * 6)
|
||||
break;
|
||||
}
|
||||
|
||||
// Three closing lines, bottom left. The first used to be an addr2line
|
||||
|
|
@ -456,12 +499,13 @@ paint(char *reason, addr_t *pcs, int npcs)
|
|||
//
|
||||
// Kept under about 45 characters each: the QR card is on the right, and the
|
||||
// 62-character command line this replaces used to run underneath it.
|
||||
gfx_text_at(left, sh - ch * 4,
|
||||
text_at(left, sh - ch * 4,
|
||||
"This report is in /proc/kmsg after a restart.", PSOGM_DIM);
|
||||
gfx_text_at(left, sh - ch * 4 + ch + 4,
|
||||
text_at(left, sh - ch * 4 + ch + 4,
|
||||
"schdbg, or Ctrl-G on the console, asks more.", PSOGM_DIM);
|
||||
gfx_text_at(left, sh - ch * 4 + (ch + 4) * 2,
|
||||
text_at(left, sh - ch * 4 + (ch + 4) * 2,
|
||||
"PSOGM -- Purple Screen of Guru Meditation", PSOGM_DIM);
|
||||
gfx_flush_all();
|
||||
}
|
||||
|
||||
// Same report, down the serial line. This is the copy that survives: it is what
|
||||
|
|
|
|||
Loading…
Reference in a new issue