code: drawterm

Download patch

ref: bc76055c7e37f1cd087a6d274eb56a41b2fc25a7
parent: fee6fddeb6c78274abc9b2cffc9ce07d336ea8a1
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Sat Nov 25 23:46:59 EST 2017

devcons: add #c/kmesg, redraw kmesg buffer after resize

when resizing the screen, the text contents where lost.
with the kmesg buffer, we can just re-render the text.

--- a/kern/dat.h
+++ b/kern/dat.h
@@ -350,8 +350,8 @@
 
 struct Proc
 {
-	uint		state;
-	uint		mach;
+	uint	state;
+	uint	mach;
 
 	ulong	pid;
 	ulong	parentpid;
@@ -358,7 +358,7 @@
 
 	Pgrp	*pgrp;		/* Process group for namespace */
 	Fgrp	*fgrp;		/* File descriptor group */
-	Rgrp *rgrp;
+	Rgrp	*rgrp;
 
 	Lock	rlock;		/* sync sleep/wakeup with postnote */
 	Rendez	*r;		/* rendezvous point slept on */
@@ -372,21 +372,21 @@
 
 	int	nerrlab;
 	Label	errlab[NERR];
-	char user[KNAMELEN];
+	char	user[KNAMELEN];
 	char	*syserrstr;	/* last error from a system call, errbuf0 or 1 */
 	char	*errstr;	/* reason we're unwinding the error stack, errbuf1 or 0 */
 	char	errbuf0[ERRMAX];
 	char	errbuf1[ERRMAX];
 	char	genbuf[128];	/* buffer used e.g. for last name element from namec */
-	char text[KNAMELEN];
+	char	text[KNAMELEN];
 
 	Chan	*slash;
 	Chan	*dot;
 
-	Proc		*qnext;
+	Proc	*qnext;
 
 	void	(*fn)(void*);
-	void *arg;
+	void	*arg;
 
 	char oproc[1024];	/* reserved for os */
 
@@ -469,6 +469,16 @@
 
 #define DEVDOTDOT -1
 
-extern Proc *_getproc(void);
-extern void _setproc(Proc*);
+extern Proc	*_getproc(void);
+extern void	_setproc(Proc*);
 #define	up	(_getproc())
+
+/*
+ * Log console output so it can be retrieved via /dev/kmesg.
+ * This is good for catching boot-time messages after the fact.
+ */
+struct {
+	Lock lk;
+	uint n;
+	char buf[16384];
+} kmesg;
--- a/kern/devcons.c
+++ b/kern/devcons.c
@@ -97,6 +97,35 @@
 	qnoblock(kbdq, 1);
 }
 
+static void
+kmesgputs(char *str, int n)
+{
+	uint nn, d;
+
+	ilock(&kmesg.lk);
+	/* take the tail of huge writes */
+	if(n > sizeof kmesg.buf){
+		d = n - sizeof kmesg.buf;
+		str += d;
+		n -= d;
+	}
+
+	/* slide the buffer down to make room */
+	nn = kmesg.n;
+	if(nn + n >= sizeof kmesg.buf){
+		d = nn + n - sizeof kmesg.buf;
+		if(d)
+			memmove(kmesg.buf, kmesg.buf+d, sizeof kmesg.buf-d);
+		nn -= d;
+	}
+
+	/* copy the data in */
+	memmove(kmesg.buf+nn, str, n);
+	nn += n;
+	kmesg.n = nn;
+	iunlock(&kmesg.lk);
+}
+
 /*
  *   Print a string on the console.  Convert \n to \r\n for serial
  *   line consoles.  Locking of the queues is left up to the screen
@@ -107,6 +136,11 @@
 putstrn0(char *str, int n, int usewrite)
 {
 	/*
+	 *  how many different output devices do we need?
+	 */
+	kmesgputs(str, n);
+
+	/*
 	 *  if someone is reading /dev/kprint,
 	 *  put the message there.
 	 *  if not and there's an attached bit mapped display,
@@ -298,6 +332,7 @@
 	Qconsctl,
 	Qcputime,
 	Qdrivers,
+	Qkmesg,
 	Qkprint,
 	Qhostdomain,
 	Qhostowner,
@@ -331,7 +366,8 @@
 	"drivers",	{Qdrivers},	0,		0444,
 	"hostdomain",	{Qhostdomain},	DOMLEN,		0664,
 	"hostowner",	{Qhostowner},	0,	0664,
-	"kprint",		{Qkprint, 0, QTEXCL},	0,	DMEXCL|0440,
+	"kmesg",	{Qkmesg},	0,		0440,
+	"kprint",	{Qkprint, 0, QTEXCL},	0,	DMEXCL|0440,
 	"null",		{Qnull},	0,		0666,
 	"osversion",	{Qosversion},	0,		0444,
 	"pgrpid",	{Qpgrpid},	NUMSIZE,	0444,
@@ -554,6 +590,22 @@
 	case Qcputime:
 		return 0;
 
+	case Qkmesg:
+		/*
+		 * This is unlocked to avoid tying up a process
+		 * that's writing to the buffer.  kmesg.n never 
+		 * gets smaller, so worst case the reader will
+		 * see a slurred buffer.
+		 */
+		if(off >= kmesg.n)
+			n = 0;
+		else{
+			if(off+n > kmesg.n)
+				n = kmesg.n - off;
+			memmove(buf, kmesg.buf+off, n);
+		}
+		return n;
+		
 	case Qkprint:
 		return qread(kprintoq, buf, n);
 
--- a/kern/term.c
+++ b/kern/term.c
@@ -8,29 +8,19 @@
 #include	<memdraw.h>
 #include	"screen.h"
 
-#define	MINX	8
-#define	Backgnd		0xFF	/* white */
+extern Memimage		*gscreen;
 
-		Memsubfont	*memdefont;
-		
-struct{
-	Point	pos;
-	int	bwid;
-}out;
+static Memsubfont	*memdefont;
+static Lock		screenlock;
+static Memimage		*conscol;
+static Memimage		*back;
+static Rectangle	flushr;
+static Rectangle	window;
+static Point		curpos;
+static int		h;
 
-Lock	screenlock;
+static void termscreenputs(char*, int);
 
-Memimage *conscol;
-Memimage *back;
-extern Memimage *gscreen;
-
-static Rectangle flushr;
-static Rectangle window;
-static Point curpos;
-static int h;
-static void	termscreenputs(char*, int);
-
-
 static void
 screenflush(void)
 {
@@ -84,6 +74,8 @@
 	window.max.y = window.min.y+((window.max.y-window.min.y)/h)*h;
 	flushmemscreen(gscreen->r);
 	qunlock(&drawlock);
+
+	termscreenputs(kmesg.buf, kmesg.n);
 }
 
 static struct {
@@ -137,9 +129,6 @@
 terminit(void)
 {
 	memdefont = getmemdefont();
-	out.pos.x = MINX;
-	out.pos.y = 0;
-	out.bwid = memdefont->info[' '].width;
 	screenwin();
 	screenputs = termscreenputs;
 	kproc("resize", resizeproc, nil);