when resizing the screen, the text contents where lost. with the kmesg buffer, we can just re-render the text.
Unified · Split
| @@ -350,15 +350,15 @@ enum · 349 unmodified lines | |||
| 350 | 350 | ||
| 351 | struct Proc | 351 | struct Proc |
| 352 | { | 352 | { |
| 353 | uint state; | 353 | uint state; |
| 354 | uint mach; | 354 | uint mach; |
| 355 | 355 | ||
| 356 | ulong pid; | 356 | ulong pid; |
| 357 | ulong parentpid; | 357 | ulong parentpid; |
| 358 | 358 | ||
| 359 | Pgrp *pgrp; /* Process group for namespace */ | 359 | Pgrp *pgrp; /* Process group for namespace */ |
| 360 | Fgrp *fgrp; /* File descriptor group */ | 360 | Fgrp *fgrp; /* File descriptor group */ |
| 361 | Rgrp *rgrp; | 361 | Rgrp *rgrp; |
| 362 | 362 | ||
| 363 | Lock rlock; /* sync sleep/wakeup with postnote */ | 363 | Lock rlock; /* sync sleep/wakeup with postnote */ |
| 364 | Rendez *r; /* rendezvous point slept on */ | 364 | Rendez *r; /* rendezvous point slept on */ |
| @@ -372,21 +372,21 @@ struct Proc · 7 unmodified lines | |||
| 372 | 372 | ||
| 373 | int nerrlab; | 373 | int nerrlab; |
| 374 | Label errlab[NERR]; | 374 | Label errlab[NERR]; |
| 375 | char user[KNAMELEN]; | 375 | char user[KNAMELEN]; |
| 376 | char *syserrstr; /* last error from a system call, errbuf0 or 1 */ | 376 | char *syserrstr; /* last error from a system call, errbuf0 or 1 */ |
| 377 | char *errstr; /* reason we're unwinding the error stack, errbuf1 or 0 */ | 377 | char *errstr; /* reason we're unwinding the error stack, errbuf1 or 0 */ |
| 378 | char errbuf0[ERRMAX]; | 378 | char errbuf0[ERRMAX]; |
| 379 | char errbuf1[ERRMAX]; | 379 | char errbuf1[ERRMAX]; |
| 380 | char genbuf[128]; /* buffer used e.g. for last name element from namec */ | 380 | char genbuf[128]; /* buffer used e.g. for last name element from namec */ |
| 381 | char text[KNAMELEN]; | 381 | char text[KNAMELEN]; |
| 382 | 382 | ||
| 383 | Chan *slash; | 383 | Chan *slash; |
| 384 | Chan *dot; | 384 | Chan *dot; |
| 385 | 385 | ||
| 386 | Proc *qnext; | 386 | Proc *qnext; |
| 387 | 387 | ||
| 388 | void (*fn)(void*); | 388 | void (*fn)(void*); |
| 389 | void *arg; | 389 | void *arg; |
| 390 | 390 | ||
| 391 | char oproc[1024]; /* reserved for os */ | 391 | char oproc[1024]; /* reserved for os */ |
| 392 | 392 | ||
| @@ -469,6 +469,16 @@ enum · 76 unmodified lines | |||
| 469 | 469 | ||
| 470 | #define DEVDOTDOT -1 | 470 | #define DEVDOTDOT -1 |
| 471 | 471 | ||
| 472 | extern Proc *_getproc(void); | 472 | extern Proc *_getproc(void); |
| 473 | extern void _setproc(Proc*); | 473 | extern void _setproc(Proc*); |
| 474 | #define up (_getproc()) | 474 | #define up (_getproc()) |
| 475 | |||
| 476 | /* | ||
| 477 | * Log console output so it can be retrieved via /dev/kmesg. | ||
| 478 | * This is good for catching boot-time messages after the fact. | ||
| 479 | */ | ||
| 480 | struct { | ||
| 481 | Lock lk; | ||
| 482 | uint n; | ||
| 483 | char buf[16384]; | ||
| 484 | } kmesg; | ||
| @@ -97,6 +97,35 @@ printinit(void) · 96 unmodified lines | |||
| 97 | qnoblock(kbdq, 1); | 97 | qnoblock(kbdq, 1); |
| 98 | } | 98 | } |
| 99 | 99 | ||
| 100 | static void | ||
| 101 | kmesgputs(char *str, int n) | ||
| 102 | { | ||
| 103 | uint nn, d; | ||
| 104 | |||
| 105 | ilock(&kmesg.lk); | ||
| 106 | /* take the tail of huge writes */ | ||
| 107 | if(n > sizeof kmesg.buf){ | ||
| 108 | d = n - sizeof kmesg.buf; | ||
| 109 | str += d; | ||
| 110 | n -= d; | ||
| 111 | } | ||
| 112 | |||
| 113 | /* slide the buffer down to make room */ | ||
| 114 | nn = kmesg.n; | ||
| 115 | if(nn + n >= sizeof kmesg.buf){ | ||
| 116 | d = nn + n - sizeof kmesg.buf; | ||
| 117 | if(d) | ||
| 118 | memmove(kmesg.buf, kmesg.buf+d, sizeof kmesg.buf-d); | ||
| 119 | nn -= d; | ||
| 120 | } | ||
| 121 | |||
| 122 | /* copy the data in */ | ||
| 123 | memmove(kmesg.buf+nn, str, n); | ||
| 124 | nn += n; | ||
| 125 | kmesg.n = nn; | ||
| 126 | iunlock(&kmesg.lk); | ||
| 127 | } | ||
| 128 | |||
| 100 | /* | 129 | /* |
| 101 | * Print a string on the console. Convert \n to \r\n for serial | 130 | * Print a string on the console. Convert \n to \r\n for serial |
| 102 | * line consoles. Locking of the queues is left up to the screen | 131 | * line consoles. Locking of the queues is left up to the screen |
| @@ -106,6 +135,11 @@ printinit(void) · 3 unmodified lines | |||
| 106 | static void | 135 | static void |
| 107 | putstrn0(char *str, int n, int usewrite) | 136 | putstrn0(char *str, int n, int usewrite) |
| 108 | { | 137 | { |
| 138 | /* | ||
| 139 | * how many different output devices do we need? | ||
| 140 | */ | ||
| 141 | kmesgputs(str, n); | ||
| 142 | |||
| 109 | /* | 143 | /* |
| 110 | * if someone is reading /dev/kprint, | 144 | * if someone is reading /dev/kprint, |
| 111 | * put the message there. | 145 | * put the message there. |
| @@ -298,6 +332,7 @@ enum{ · 186 unmodified lines | |||
| 298 | Qconsctl, | 332 | Qconsctl, |
| 299 | Qcputime, | 333 | Qcputime, |
| 300 | Qdrivers, | 334 | Qdrivers, |
| 335 | Qkmesg, | ||
| 301 | Qkprint, | 336 | Qkprint, |
| 302 | Qhostdomain, | 337 | Qhostdomain, |
| 303 | Qhostowner, | 338 | Qhostowner, |
| @@ -331,7 +366,8 @@ static Dirtab consdir[]={ · 27 unmodified lines | |||
| 331 | "drivers", {Qdrivers}, 0, 0444, | 366 | "drivers", {Qdrivers}, 0, 0444, |
| 332 | "hostdomain", {Qhostdomain}, DOMLEN, 0664, | 367 | "hostdomain", {Qhostdomain}, DOMLEN, 0664, |
| 333 | "hostowner", {Qhostowner}, 0, 0664, | 368 | "hostowner", {Qhostowner}, 0, 0664, |
| 334 | "kprint", {Qkprint, 0, QTEXCL}, 0, DMEXCL|0440, | 369 | "kmesg", {Qkmesg}, 0, 0440, |
| 370 | "kprint", {Qkprint, 0, QTEXCL}, 0, DMEXCL|0440, | ||
| 335 | "null", {Qnull}, 0, 0666, | 371 | "null", {Qnull}, 0, 0666, |
| 336 | "osversion", {Qosversion}, 0, 0444, | 372 | "osversion", {Qosversion}, 0, 0444, |
| 337 | "pgrpid", {Qpgrpid}, NUMSIZE, 0444, | 373 | "pgrpid", {Qpgrpid}, NUMSIZE, 0444, |
| @@ -554,6 +590,22 @@ consread(Chan *c, void *buf, long n, vlong off) · 216 unmodified lines | |||
| 554 | case Qcputime: | 590 | case Qcputime: |
| 555 | return 0; | 591 | return 0; |
| 556 | 592 | ||
| 593 | case Qkmesg: | ||
| 594 | /* | ||
| 595 | * This is unlocked to avoid tying up a process | ||
| 596 | * that's writing to the buffer. kmesg.n never | ||
| 597 | * gets smaller, so worst case the reader will | ||
| 598 | * see a slurred buffer. | ||
| 599 | */ | ||
| 600 | if(off >= kmesg.n) | ||
| 601 | n = 0; | ||
| 602 | else{ | ||
| 603 | if(off+n > kmesg.n) | ||
| 604 | n = kmesg.n - off; | ||
| 605 | memmove(buf, kmesg.buf+off, n); | ||
| 606 | } | ||
| 607 | return n; | ||
| 608 | |||
| 557 | case Qkprint: | 609 | case Qkprint: |
| 558 | return qread(kprintoq, buf, n); | 610 | return qread(kprintoq, buf, n); |
| 559 | 611 | ||
| @@ -8,28 +8,18 @@ · 7 unmodified lines | |||
| 8 | #include <memdraw.h> | 8 | #include <memdraw.h> |
| 9 | #include "screen.h" | 9 | #include "screen.h" |
| 10 | 10 | ||
| 11 | #define MINX 8 | 11 | extern Memimage *gscreen; |
| 12 | #define Backgnd 0xFF /* white */ | ||
| 13 | 12 | ||
| 14 | Memsubfont *memdefont; | 13 | static Memsubfont *memdefont; |
| 15 | 14 | static Lock screenlock; | |
| 16 | struct{ | 15 | static Memimage *conscol; |
| 17 | Point pos; | 16 | static Memimage *back; |
| 18 | int bwid; | 17 | static Rectangle flushr; |
| 19 | }out; | 18 | static Rectangle window; |
| 20 | 19 | static Point curpos; | |
| 21 | Lock screenlock; | 20 | static int h; |
| 22 | |||
| 23 | Memimage *conscol; | ||
| 24 | Memimage *back; | ||
| 25 | extern Memimage *gscreen; | ||
| 26 | |||
| 27 | static Rectangle flushr; | ||
| 28 | static Rectangle window; | ||
| 29 | static Point curpos; | ||
| 30 | static int h; | ||
| 31 | static void termscreenputs(char*, int); | ||
| 32 | 21 | ||
| 22 | static void termscreenputs(char*, int); | ||
| 33 | 23 | ||
| 34 | static void | 24 | static void |
| 35 | screenflush(void) | 25 | screenflush(void) |
| @@ -84,6 +74,8 @@ screenwin(void) · 48 unmodified lines | |||
| 84 | window.max.y = window.min.y+((window.max.y-window.min.y)/h)*h; | 74 | window.max.y = window.min.y+((window.max.y-window.min.y)/h)*h; |
| 85 | flushmemscreen(gscreen->r); | 75 | flushmemscreen(gscreen->r); |
| 86 | qunlock(&drawlock); | 76 | qunlock(&drawlock); |
| 77 | |||
| 78 | termscreenputs(kmesg.buf, kmesg.n); | ||
| 87 | } | 79 | } |
| 88 | 80 | ||
| 89 | static struct { | 81 | static struct { |
| @@ -137,9 +129,6 @@ void · 47 unmodified lines | |||
| 137 | terminit(void) | 129 | terminit(void) |
| 138 | { | 130 | { |
| 139 | memdefont = getmemdefont(); | 131 | memdefont = getmemdefont(); |
| 140 | out.pos.x = MINX; | ||
| 141 | out.pos.y = 0; | ||
| 142 | out.bwid = memdefont->info[' '].width; | ||
| 143 | screenwin(); | 132 | screenwin(); |
| 144 | screenputs = termscreenputs; | 133 | screenputs = termscreenputs; |
| 145 | kproc("resize", resizeproc, nil); | 134 | kproc("resize", resizeproc, nil); |