public inbox for gentoo-user@lists.gentoo.org
 help / color / mirror / Atom feed
From: Alan Mackenzie <acm@muc.de>
To: gentoo-user@lists.gentoo.org
Subject: Re: [gentoo-user] Console scrollback is back again!
Date: Tue, 6 Apr 2021 14:32:46 +0000	[thread overview]
Message-ID: <YGxxDrbCw2ueEdUe@ACM> (raw)
In-Reply-To: <m3mtubbiwc.wl-covici@ccs.covici.com>

[-- Attachment #1: Type: text/plain, Size: 723 bytes --]

Hello, John

On Tue, Apr 06, 2021 at 10:13:39 -0400, John Covici wrote:

> On Tue, 06 Apr 2021 09:14:23 -0400,
> Peter Humphrey wrote:

> > On Monday, 5 April 2021 19:13:18 BST Alan Mackenzie wrote:

> > > We'll see how people react to it here, first.

> > You're my hero!

> Would this patch work on 5.4.96 and following?

No, there is a slight difference (two struct fields moved and renamed)
between 5.4 and 5.10.

For 5.4, please use the attached patch instead.  It has been tested on
5.4.80-r1 and 5.4.97.

> -- 
> Your life is like a penny.  You're going to lose it.  The question is:
> How do
> you spend it?

>          John Covici wb2una
>          covici@ccs.covici.com

-- 
Alan Mackenzie (Nuremberg, Germany).


[-- Attachment #2: diff.20210405b.diff --]
[-- Type: text/plain, Size: 23284 bytes --]

--- drivers/video/console/Kconfig.orig	2021-03-31 19:14:48.186140856 +0000
+++ drivers/video/console/Kconfig	2021-04-05 13:41:20.967713154 +0000
@@ -79,6 +79,55 @@
 	help
 	  Low-level framebuffer-based console driver.
 
+config FRAMEBUFFER_CONSOLE_SOFT_SCROLLBACK
+	bool "Enable Scrollback Buffer in System RAM"
+	depends on FB=y && FRAMEBUFFER_CONSOLE
+	default y
+	select FRAMEBUFFER_CONSOLE_SOFT_SCROLLBACK_PERSISTENT_ENABLE_BY_DEFAULT
+	help
+	  This option creates scrollback buffers for each framebuffer console,
+	  or one buffer for them all.  These buffers are allocated dynamically
+	  during initialisation.
+
+	  If you want this feature, say 'Y' here and enter the amount of
+	  RAM to allocate for this buffer.  If unsure, say 'N'.
+
+config FRAMEBUFFER_CONSOLE_SOFT_SCROLLBACK_SIZE
+       int "Scrollback Buffer Size (in KB)"
+       depends on FRAMEBUFFER_CONSOLE_SOFT_SCROLLBACK
+       range 1 1024
+       default "128"
+       help
+       	  Enter the amount of System RAM to allocate for each scrollback
+	  buffer of framebuffer consoles in kilobytes.  Each character
+	  position on the video takes 2 bytes of storage.  128k will give you
+	  approximately 4 240x67 screenfuls of scrollback buffer.
+
+config FRAMEBUFFER_CONSOLE_SOFT_SCROLLBACK_PERSISTENT_ENABLE_BY_DEFAULT
+	bool "Persistent Scrollback History for each framebuffer console by default"
+	depends on FB=y && FRAMEBUFFER_CONSOLE && FRAMEBUFFER_CONSOLE_SOFT_SCROLLBACK
+	default y
+	help
+
+	  Note: this option's value N has not (?yet) been implemented (2021-04).
+
+	  Say Y here if the scrollback history should persist by default when
+	  switching between consoles. Otherwise, the scrollback history will
+	  be flushed the first time a scroll-up operation occurs on the new
+	  console after the console is switched. STOUGH!!!  FIXME!!! This
+	  feature can also be enabled using the boot command line parameter
+	  'vgacon.scrollback_persistent=1'.
+
+	  This feature might break your tool of choice to flush the scrollback
+	  buffer, e.g. clear(1) will work fine but Debian's clear_console(1)
+	  will be broken, which might cause security issues.
+	  You can use the escape sequence \e[3J instead if this feature is
+	  activated.
+
+	  Note that a buffer of VGACON_SOFT_SCROLLBACK_SIZE is taken for each
+	  created tty device.
+	  So if you use a RAM-constrained system, say N here.
+
 config FRAMEBUFFER_CONSOLE_DETECT_PRIMARY
        bool "Map the console to the primary display device"
        depends on FRAMEBUFFER_CONSOLE
--- drivers/tty/vt/vt.orig.c	2020-11-28 17:14:38.523649992 +0000
+++ drivers/tty/vt/vt.c	2021-04-05 14:33:47.743786578 +0000
@@ -142,6 +142,13 @@
 #define DEFAULT_BELL_DURATION	(HZ/8)
 #define DEFAULT_CURSOR_BLINK_MS	200
 
+/* NEW STOUGH, 2021-04-01 */
+#ifdef CONFIG_FRAMEBUFFER_CONSOLE_SOFT_SCROLLBACK
+static unsigned int console_soft_scrollback_size =
+	1024 * CONFIG_FRAMEBUFFER_CONSOLE_SOFT_SCROLLBACK_SIZE;
+#endif
+/* END OF NEW STOUGH */
+
 struct vc vc_cons [MAX_NR_CONSOLES];
 
 #ifndef VT_SINGLE_DRIVER
@@ -294,7 +301,7 @@
 static inline unsigned short *screenpos(struct vc_data *vc, int offset, int viewed)
 {
 	unsigned short *p;
-	
+
 	if (!viewed)
 		p = (unsigned short *)(vc->vc_origin + offset);
 	else if (!vc->vc_sw->con_screen_pos)
@@ -623,6 +630,232 @@
 	}
 }
 
+/* NEW STOUGH, 2021-03-31 */
+#ifdef CONFIG_FRAMEBUFFER_CONSOLE_SOFT_SCROLLBACK
+/* NEW STOUGH, 2021-04-01 */
+static void con_update_softback(struct vc_data *vc)
+{
+	int l = vc->vc_softback_size / vc->vc_size_row;
+	if (l > 5)
+	{
+		vc->vc_softback_end = vc->vc_softback_buf + l * vc->vc_size_row;
+		vc->vc_softback_top = vc->vc_softback_buf; /* STOUGH, 2021-04-04 */
+	}
+	else
+		/* Smaller scrollback makes no sense, and 0 would screw
+		   the operation totally */
+		vc->vc_softback_top = 0;
+}
+
+static int concon_set_origin(struct vc_data *vc)
+{
+	if (vc->vc_softback_lines)
+		concon_scrolldelta(vc, vc->vc_softback_lines);
+	return 0;
+}
+/* END OF NEW STOUGH */
+
+#define advance_row(p, delta) (unsigned short *)((unsigned long)(p) + (delta) * vc->vc_size_row)
+
+static void con_redraw_softback(struct vc_data *vc, /* struct display *p, */
+				long delta)
+{
+	int count = vc->vc_rows;
+	unsigned short *d, *s;
+	unsigned long n;
+	int line = 0;
+
+	/* NEW STOUGH, 2021-04-04 */
+	if (!vc->vc_softback_lines)
+		vc->vc_char_at_pos = scr_readw((u16 *)vc->vc_pos);
+	/* END OF NEW STOUGH */
+
+	d = (u16 *) vc->vc_softback_curr;
+	if (d == (u16 *) vc->vc_softback_in)
+		d = (u16 *) vc->vc_origin;
+	n = vc->vc_softback_curr + delta * vc->vc_size_row;
+	vc->vc_softback_lines -= delta;
+	if (delta < 0) {
+		if (vc->vc_softback_curr < vc->vc_softback_top
+		    && n < vc->vc_softback_buf) {
+			n += vc->vc_softback_end - vc->vc_softback_buf;
+			if (n < vc->vc_softback_top) {
+				vc->vc_softback_lines -=
+				    (vc->vc_softback_top - n) / vc->vc_size_row;
+				n = vc->vc_softback_top;
+			}
+		} else if (vc->vc_softback_curr >= vc->vc_softback_top
+			   && n < vc->vc_softback_top) {
+			vc->vc_softback_lines -=
+			    (vc->vc_softback_top - n) / vc->vc_size_row;
+			n = vc->vc_softback_top;
+		}
+	} else {
+		if (vc->vc_softback_curr > vc->vc_softback_in
+		    && n >= vc->vc_softback_end) {
+			n += vc->vc_softback_buf - vc->vc_softback_end;
+			if (n > vc->vc_softback_in) {
+				n = vc->vc_softback_in;
+				vc->vc_softback_lines = 0;
+			}
+		} else if (vc->vc_softback_curr <= vc->vc_softback_in
+			   && n > vc->vc_softback_in) {
+			n = vc->vc_softback_in;
+			vc->vc_softback_lines = 0;
+		}
+	}
+	if (n == vc->vc_softback_curr)
+		return;
+	vc->vc_softback_curr = n;
+	/* NEW STOUGH, 2021-04-04 */
+	/* If we're not scrolled any more, restore the character to the cursor
+	 * position */
+	if (!vc->vc_softback_lines)
+		scr_writew(vc->vc_char_at_pos, (u16 *)vc->vc_pos);
+	/* END OF NEW STOUGH */
+	s = (u16 *) vc->vc_softback_curr;
+	if (s == (u16 *) vc->vc_softback_in)
+		s = (u16 *) vc->vc_origin;
+	while (count--) {
+		unsigned short *start;
+		unsigned short *le;
+		unsigned short c;
+		int x = 0;
+		unsigned short attr = 1;
+
+		start = s;
+		le = advance_row(s, 1);
+		/* NEW STOUGH, 2021-04-04 */
+		/* Temporarily overwrite the character at the cursor position
+		 * with the one we actually want to see on the screen.  */
+		if (count == vc->vc_rows - vc->vc_y - 1)
+		{
+			c = scr_readw((u16 *)(s + vc->vc_x));
+			scr_writew(c, (u16 *)vc->vc_pos);
+			vc->vc_sw->con_putcs
+				(vc, (u16 *)vc->vc_pos, 1, line, vc->vc_x);
+		}
+		/* END OF NEW STOUGH */
+		do {
+			c = scr_readw(s);
+			if (attr != (c & 0xff00)) {
+				attr = c & 0xff00;
+				if (s > start) {
+					vc->vc_sw->con_putcs(
+						vc, start, s - start,
+						line, x);
+					x += s - start;
+					start = s;
+				}
+			}
+			if (c == scr_readw(d)) {
+				if (s > start) {
+					vc->vc_sw->con_putcs(
+						vc, start, s - start,
+						line, x);
+					x += s - start + 1;
+					start = s + 1;
+				} else {
+					x++;
+					start++;
+				}
+			}
+			s++;
+			d++;
+		} while (s < le);
+		if (s > start)
+			vc->vc_sw->con_putcs(vc, start, s - start, line, x);
+		line++;
+		if (d == (u16 *) vc->vc_softback_end)
+			d = (u16 *) vc->vc_softback_buf;
+		if (d == (u16 *) vc->vc_softback_in)
+			d = (u16 *) vc->vc_origin;
+		if (s == (u16 *) vc->vc_softback_end)
+			s = (u16 *) vc->vc_softback_buf;
+		if (s == (u16 *) vc->vc_softback_in)
+			s = (u16 *) vc->vc_origin;
+	}
+}
+/* END OF NEW STOUGH */
+
+/* NEW STOUGH, 2021-04-01 */
+static inline void con_softback_note(struct vc_data *vc, int t,
+				     int count)
+{
+	unsigned short *p;
+
+	if (vc->vc_num != fg_console)
+		return;
+	p = (unsigned short *) (vc->vc_origin + t * vc->vc_size_row);
+
+	while (count) {
+		scr_memcpyw((u16 *) vc->vc_softback_in, p, vc->vc_size_row);
+		count--;
+		p = advance_row(p, 1);
+		vc->vc_softback_in += vc->vc_size_row;
+		if (vc->vc_softback_in == vc->vc_softback_end)
+			vc->vc_softback_in = vc->vc_softback_buf;
+		if (vc->vc_softback_in == vc->vc_softback_top) {
+			vc->vc_softback_top += vc->vc_size_row;
+			if (vc->vc_softback_top == vc->vc_softback_end)
+				vc->vc_softback_top = vc->vc_softback_buf;
+		}
+	}
+	vc->vc_softback_curr = vc->vc_softback_in;
+}
+
+void concon_scrolldelta(struct vc_data *vc, int lines)
+{
+	/* struct display *disp = &fb_display[fg_console]; */
+	/* int offset, limit, scrollback_old; */
+
+	if (vc->vc_softback_top) {
+		if (vc->vc_num != fg_console)
+			return;
+		if (vc->vc_mode != KD_TEXT || !lines)
+			return;
+#if 0
+		if (logo_shown >= 0) {
+			struct vc_data *conp2 = vc_cons[logo_shown].d;
+
+			if (conp2->vc_top == logo_lines
+			    && conp2->vc_bottom == conp2->vc_rows)
+				conp2->vc_top = 0;
+			if (logo_shown == vc->vc_num) {
+				unsigned long p, q;
+				int i;
+
+				p = vc->vc_softback_in;
+				q = vc->vc_origin +
+				    logo_lines * vc->vc_size_row;
+				for (i = 0; i < logo_lines; i++) {
+					if (p == vc->vc_softback_top)
+						break;
+					if (p == vc->vc_softback_buf)
+						p = vc->vc_softback_end;
+					p -= vc->vc_size_row;
+					q -= vc->vc_size_row;
+					scr_memcpyw((u16 *) q, (u16 *) p,
+						    vc->vc_size_row);
+				}
+				vc->vc_softback_in = vc->vc_softback_curr = p;
+				update_region(vc, vc->vc_origin,
+					      logo_lines * vc->vc_cols);
+			}
+			logo_shown = FBCON_LOGO_CANSHOW;
+		}
+#endif
+		vc->vc_sw->con_cursor(vc, CM_ERASE /* | CM_SOFTBACK */);
+		con_redraw_softback(vc, /* disp, */ lines);
+		/* NEW STOUGH, 2021-04-04 */
+		if (!vc->vc_softback_lines)
+			/* END OF NEW STOUGH */
+			vc->vc_sw->con_cursor(vc, CM_DRAW /* | CM_SOFTBACK */);
+	}
+}
+
+/* END OF NEW STOUGH */
+#endif  /* CONFIG_FRAMEBUFFER_CONSOLE_SOFT_SCROLLBACK */
 
 static void con_scroll(struct vc_data *vc, unsigned int t, unsigned int b,
 		enum con_scroll dir, unsigned int nr)
@@ -633,6 +866,12 @@
 		nr = b - t - 1;
 	if (b > vc->vc_rows || t >= b || nr < 1)
 		return;
+	/* NEW STOUGH, 2021-04-01 */
+#ifdef CONFIG_FRAMEBUFFER_CONSOLE_SOFT_SCROLLBACK
+	if (dir == SM_UP && vc->vc_softback_top)
+		con_softback_note (vc, t, nr);
+#endif
+	/* END OF NEW STOUGH */
 	vc_uniscr_scroll(vc, t, b, dir, nr);
 	if (con_is_visible(vc) && vc->vc_sw->con_scroll(vc, t, b, dir, nr))
 		return;
@@ -648,6 +887,72 @@
 	scr_memsetw(clear, vc->vc_video_erase_char, vc->vc_size_row * nr);
 }
 
+#ifdef CONFIG_FRAMEBUFFER_CONSOLE_SOFT_SCROLLBACK
+static void do_update_region(struct vc_data *vc, unsigned long start, int count)
+{
+	unsigned int xx, yy, offset;
+	u16 *p;
+
+	/* NEW STOUGH, 2021-04-03 */
+	unsigned long origin =
+		(start >= vc->vc_softback_buf && start < vc->vc_softback_end)
+		? start >= vc->vc_softback_curr
+		  ? vc->vc_softback_curr
+		  : vc->vc_softback_curr
+		    - (vc->vc_softback_end - vc->vc_softback_buf)
+		: vc->vc_origin;
+	/* END OF NEW STOUGH */
+	p = (u16 *) start;
+	/* OLD STOUGH, 2021-04-03 */
+	/* if (!vc->vc_sw->con_getxy) { */
+		/* END OF OLD STOUGH */
+		offset = (start - origin) / 2; /* STOUGH, 2021-04-03 */
+		xx = offset % vc->vc_cols;
+		yy = offset / vc->vc_cols;
+		/* OLD STOUGH, 2021-04-03 */
+	/* } else { */
+	/* 	int nxx, nyy; */
+	/* 	start = vc->vc_sw->con_getxy(vc, start, &nxx, &nyy); */
+	/* 	xx = nxx; yy = nyy; */
+	/* } */
+		/* END OF OLD STOUGH */
+	for(;;) {
+		u16 attrib = scr_readw(p) & 0xff00;
+		int startx = xx;
+		u16 *q = p;
+		while (xx < vc->vc_cols && count) {
+			if (attrib != (scr_readw(p) & 0xff00)) {
+				if (p > q)
+					vc->vc_sw->con_putcs(vc, q, p-q, yy, startx);
+				startx = xx;
+				q = p;
+				attrib = scr_readw(p) & 0xff00;
+			}
+			p++;
+			xx++;
+			count--;
+		}
+		if (p > q)
+			vc->vc_sw->con_putcs(vc, q, p-q, yy, startx);
+		/* NEW STOUGH, 2021-04-03 */
+		if (p == (u16 *) vc->vc_softback_end)
+			p = (u16 *)vc->vc_softback_buf;
+		if (p == (u16 *) vc->vc_softback_in)
+			p = (u16 *)vc->vc_origin;
+		/* END OF NEW STOUGH */
+		if (!count)
+			break;
+		xx = 0;
+		yy++;
+		/* OLD STOUGH, 2021-04-03 */
+		/* if (vc->vc_sw->con_getxy) { */
+		/* 	p = (u16 *)start; */
+		/* 	start = vc->vc_sw->con_getxy(vc, start, NULL, NULL); */
+		/* } */
+		/* END OF OLD STOUGH */
+	}
+}
+#else
 static void do_update_region(struct vc_data *vc, unsigned long start, int count)
 {
 	unsigned int xx, yy, offset;
@@ -691,6 +996,7 @@
 		}
 	}
 }
+#endif
 
 void update_region(struct vc_data *vc, unsigned long start, int count)
 {
@@ -699,7 +1005,12 @@
 	if (con_should_update(vc)) {
 		hide_cursor(vc);
 		do_update_region(vc, start, count);
-		set_cursor(vc);
+		/* NEW STOUGH, 2021-04-04 */
+#ifdef CONFIG_FRAMEBUFFER_CONSOLE_SOFT_SCROLLBACK
+		if (!vc->vc_softback_lines)
+#endif
+			/* END OF NEW STOUGH */
+			set_cursor(vc);
 	}
 }
 
@@ -751,8 +1062,8 @@
 static void update_attr(struct vc_data *vc)
 {
 	vc->vc_attr = build_attr(vc, vc->vc_color, vc->vc_intensity,
-	              vc->vc_blink, vc->vc_underline,
-	              vc->vc_reverse ^ vc->vc_decscnm, vc->vc_italic);
+		      vc->vc_blink, vc->vc_underline,
+		      vc->vc_reverse ^ vc->vc_decscnm, vc->vc_italic);
 	vc->vc_video_erase_char = (build_attr(vc, vc->vc_color, 1, vc->vc_blink, 0, vc->vc_decscnm, 0) << 8) | ' ';
 }
 
@@ -922,8 +1233,19 @@
 	WARN_CONSOLE_UNLOCKED();
 
 	if (!con_is_visible(vc) ||
+	    /* NEW STOUGH, 2021-04-01 */
+#ifdef CONFIG_FRAMEBUFFER_CONSOLE_SOFT_SCROLLBACK
+	    (
+	     !concon_set_origin (vc) &&
+	     (
+#endif
+	    /* END OF NEW STOUGH */
 	    !vc->vc_sw->con_set_origin ||
-	    !vc->vc_sw->con_set_origin(vc))
+	    !vc->vc_sw->con_set_origin(vc)
+#ifdef CONFIG_FRAMEBUFFER_CONSOLE_SOFT_SCROLLBACK
+		     ))
+#endif
+					  )
 		vc->vc_origin = (unsigned long)vc->vc_screenbuf;
 	vc->vc_visible_origin = vc->vc_origin;
 	vc->vc_scr_end = vc->vc_origin + vc->vc_screenbuf_size;
@@ -998,7 +1320,9 @@
 		hide_cursor(old_vc);
 		if (!con_is_visible(old_vc)) {
 			save_screen(old_vc);
-			set_origin(old_vc);
+			/* OLD STOUGH, 2021-04-02 */
+			/* set_origin(old_vc); */
+			/* END OF OLD STOUGH */
 		}
 		if (tty0dev)
 			sysfs_notify(&tty0dev->kobj, NULL, "active");
@@ -1011,7 +1335,9 @@
 		int update;
 		int old_was_color = vc->vc_can_do_color;
 
-		set_origin(vc);
+		/* OLD STOUGH, 2021-04-02 */
+		/* set_origin(vc); */
+		/* END OF OLD STOUGH */
 		update = vc->vc_sw->con_switch(vc);
 		set_palette(vc);
 		/*
@@ -1026,9 +1352,25 @@
 		}
 
 		if (update && vc->vc_mode != KD_GRAPHICS)
-			do_update_region(vc, vc->vc_origin, vc->vc_screenbuf_size / 2);
-	}
-	set_cursor(vc);
+			/* OLD STOUGH, 2021-04-03 */
+			/* do_update_region(vc, vc->vc_origin, vc->vc_screenbuf_size / 2); */
+			/* NEW STOUGH, 2021-04-03 */
+			do_update_region(vc,
+#ifdef CONFIG_FRAMEBUFFER_CONSOLE_SOFT_SCROLLBACK
+					 vc->vc_softback_lines
+					 ? vc->vc_softback_curr
+					 :
+#endif
+					   vc->vc_origin,
+					 vc->vc_screenbuf_size / 2);
+			/* END OF NEW STOUGH */
+	}
+	/* NEW STOUGH, 2021-04-04 */
+#ifdef CONFIG_FRAMEBUFFER_CONSOLE_SOFT_SCROLLBACK
+	if (!vc->vc_softback_lines)
+#endif
+		/* END OF NEW STOUGH */
+		set_cursor(vc);
 	if (is_switch) {
 		set_leds();
 		compute_shiftstate();
@@ -1107,12 +1449,32 @@
 	int err;
 
 	WARN_CONSOLE_UNLOCKED();
-
 	if (currcons >= MAX_NR_CONSOLES)
 		return -ENXIO;
 
 	if (vc_cons[currcons].d)
+		/* NEW STOUGH, 2021-04-05 */
+	{
+#ifdef CONFIG_FRAMEBUFFER_CONSOLE_SOFT_SCROLLBACK
+		vc = vc_cons[currcons].d;
+		if (!vc->vc_softback_size) {
+			/* vc was partially initialized by __init. */
+			vc->vc_softback_size = console_soft_scrollback_size;
+			vc->vc_softback_buf =
+				(unsigned long)kzalloc(vc->vc_softback_size, GFP_KERNEL);
+			if (vc->vc_softback_buf) {
+				vc->vc_softback_in = vc->vc_softback_top =
+					vc->vc_softback_curr = vc->vc_softback_buf;
+				vc->vc_softback_lines = 0;
+				con_update_softback(vc);
+			}
+		}
+#endif
+		/* END OF NEW STOUGH */
 		return 0;
+		/* NEW STOUGH, 2021-04-05 */
+	}
+	/* END OF NEW STOUGH */
 
 	/* due to the granularity of kmalloc, we waste some memory here */
 	/* the alloc is done in two steps, to optimize the common situation
@@ -1152,6 +1514,20 @@
 	vcs_make_sysfs(currcons);
 	atomic_notifier_call_chain(&vt_notifier_list, VT_ALLOCATE, &param);
 
+	/* NEW STOUGH, 2021-04-01 */
+#ifdef CONFIG_FRAMEBUFFER_CONSOLE_SOFT_SCROLLBACK
+	vc->vc_softback_size = console_soft_scrollback_size;
+	err = -ENOMEM;
+	vc->vc_softback_buf =
+		(unsigned long)kzalloc(vc->vc_softback_size, GFP_KERNEL);
+	if (!vc->vc_softback_buf)
+		goto err_free;
+	vc->vc_softback_in = vc->vc_softback_top = vc->vc_softback_curr =
+		vc->vc_softback_buf;
+	vc->vc_softback_lines = 0;
+	con_update_softback(vc);
+#endif
+	/* END OF NEW STOUGH */
 	return 0;
 err_free:
 	visual_deinit(vc);
@@ -1627,7 +2003,7 @@
 
 static void rgb_from_256(int i, struct rgb *c)
 {
-	if (i < 8) {            /* Standard colours. */
+	if (i < 8) {	    /* Standard colours. */
 		c->r = i&1 ? 0xaa : 0x00;
 		c->g = i&2 ? 0xaa : 0x00;
 		c->b = i&4 ? 0xaa : 0x00;
@@ -1639,7 +2015,7 @@
 		c->r = (i - 16) / 36 * 85 / 2;
 		c->g = (i - 16) / 6 % 6 * 85 / 2;
 		c->b = (i - 16) % 6 * 85 / 2;
-	} else                  /* Grayscale ramp. */
+	} else		  /* Grayscale ramp. */
 		c->r = c->g = c->b = i * 10 - 2312;
 }
 
@@ -2629,6 +3005,14 @@
 
 	param.vc = vc;
 
+	/* NEW STOUGH, 2021-04-03 */
+#ifdef CONFIG_FRAMEBUFFER_CONSOLE_SOFT_SCROLLBACK
+	/* Undo any soft scrolling - <Alt><Fn> and <Shift><PgUp/Down> do
+	   not pass through this function.  */
+	concon_set_origin (vc);
+#endif
+	/* END OF NEW STOUGH */
+
 	while (!tty->stopped && count) {
 		int orig = *buf;
 		c = orig;
@@ -2722,17 +3106,17 @@
 					&param) == NOTIFY_STOP)
 			continue;
 
-                /* If the original code was a control character we
-                 * only allow a glyph to be displayed if the code is
-                 * not normally used (such as for cursor movement) or
-                 * if the disp_ctrl mode has been explicitly enabled.
-                 * Certain characters (as given by the CTRL_ALWAYS
-                 * bitmap) are always displayed as control characters,
-                 * as the console would be pretty useless without
-                 * them; to display an arbitrary font position use the
-                 * direct-to-font zone in UTF-8 mode.
-                 */
-                ok = tc && (c >= 32 ||
+		/* If the original code was a control character we
+		 * only allow a glyph to be displayed if the code is
+		 * not normally used (such as for cursor movement) or
+		 * if the disp_ctrl mode has been explicitly enabled.
+		 * Certain characters (as given by the CTRL_ALWAYS
+		 * bitmap) are always displayed as control characters,
+		 * as the console would be pretty useless without
+		 * them; to display an arbitrary font position use the
+		 * direct-to-font zone in UTF-8 mode.
+		 */
+		ok = tc && (c >= 32 ||
 			    !(vc->vc_disp_ctrl ? (CTRL_ALWAYS >> c) & 1 :
 				  vc->vc_utf || ((CTRL_ACTION >> c) & 1)))
 			&& (c != 127 || vc->vc_disp_ctrl)
@@ -3018,7 +3402,12 @@
 	}
 	if (cnt && con_is_visible(vc))
 		vc->vc_sw->con_putcs(vc, start, cnt, vc->vc_y, start_x);
-	set_cursor(vc);
+	/* NEW STOUGH, 2021-04-04 */
+#ifdef CONFIG_FRAMEBUFFER_CONSOLE_SOFT_SCROLLBACK
+	if (!vc->vc_softback_lines)
+#endif
+		/* END OF NEW STOUGH */
+		set_cursor(vc);
 	notify_update(vc);
 
 quit:
@@ -3246,7 +3635,13 @@
 	/* if we race with con_close(), vt may be null */
 	console_lock();
 	vc = tty->driver_data;
-	if (vc)
+	if (vc
+	    /* NEW STOUGH, 2021-04-04 */
+#ifdef CONFIG_FRAMEBUFFER_CONSOLE_SOFT_SCROLLBACK
+	    && !vc->vc_softback_lines
+#endif
+	    /* END OF NEW STOUGH */
+	      )
 		set_cursor(vc);
 	console_unlock();
 }
@@ -3267,6 +3662,12 @@
 
 	vc = vc_cons[currcons].d;
 
+	/* NEW STOUGH, 2021-04-04 */
+#ifdef CONFIG_FRAMEBUFFER_CONSOLE_SOFT_SCROLLBACK
+	con_update_softback(vc);
+#endif
+	/* END OF NEW STOUGH */
+
 	/* Still being freed */
 	if (vc->port.tty) {
 		ret = -ERESTARTSYS;
@@ -3322,7 +3723,7 @@
 	tty_port_put(&vc->port);
 }
 
-static int default_color           = 7; /* white */
+static int default_color	   = 7; /* white */
 static int default_italic_color    = 2; // green (ASCII)
 static int default_underline_color = 3; // cyan (ASCII)
 module_param_named(color, default_color, int, S_IRUGO | S_IWUSR);
@@ -4024,7 +4425,7 @@
 			con_driver->desc = desc;
 			con_driver->node = i;
 			con_driver->flag = CON_DRIVER_FLAG_MODULE |
-			                   CON_DRIVER_FLAG_INIT;
+					   CON_DRIVER_FLAG_INIT;
 			con_driver->first = first;
 			con_driver->last = last;
 			retval = 0;
@@ -4325,7 +4726,12 @@
 	if (console_blank_hook)
 		console_blank_hook(0);
 	set_palette(vc);
-	set_cursor(vc);
+	/* NEW STOUGH, 2021-04-04 */
+#ifdef CONFIG_FRAMEBUFFER_CONSOLE_SOFT_SCROLLBACK
+	if (!vc->vc_softback_lines)
+#endif
+		/* END OF NEW STOUGH */
+		set_cursor(vc);
 	vt_event_post(VT_EVENT_UNBLANK, vc->vc_num, vc->vc_num);
 }
 EXPORT_SYMBOL(do_unblank_screen);
--- include/linux/console_struct.h.orig	2021-04-02 19:55:52.696177657 +0000
+++ include/linux/console_struct.h	2021-04-05 14:39:24.531805027 +0000
@@ -70,6 +70,21 @@
 	unsigned short	*vc_screenbuf;		/* In-memory character/attribute buffer */
 	unsigned int	vc_screenbuf_size;
 	unsigned char	vc_mode;		/* KD_TEXT, ... */
+	/* NEW STOUGH, 2021-03-31 */
+#ifdef CONFIG_FRAMEBUFFER_CONSOLE_SOFT_SCROLLBACK
+	unsigned int    vc_softback_size;	/* Size in bytes of scrollback buffer. */
+	unsigned long   vc_softback_buf;	/* Address of scrollback buffer. */
+	unsigned long   vc_softback_end;	/* (Just past) end of buffer. */
+	unsigned long   vc_softback_in;		/* Head pointer into circular buffer. */
+	unsigned long   vc_softback_top;	/* Tail pointer into circular buffer. */
+	unsigned long   vc_softback_curr;	/* Pos in vc_screenbuf or vc_softback_buf
+						   corresponding to visible screen. */
+	int             vc_softback_lines;	/* Number of lines currently scrolled. */
+	/* NEW STOUGH, 2021-04-04 */
+	unsigned short  vc_char_at_pos;		/* Char at vc_pos when no soft scroll */
+	/* END OF NEW STOUGH. */
+#endif
+	/* END OF NEW STOUGH */
 	/* attributes for all characters on screen */
 	unsigned char	vc_attr;		/* Current attributes */
 	unsigned char	vc_def_color;		/* Default colors */
--- drivers/video/fbdev/core/fbcon.c.orig	2021-04-02 19:58:46.332168089 +0000
+++ drivers/video/fbdev/core/fbcon.c	2021-04-05 14:41:32.128812016 +0000
@@ -3115,6 +3115,11 @@
 	.con_font_default	= fbcon_set_def_font,
 	.con_font_copy 		= fbcon_copy_font,
 	.con_set_palette 	= fbcon_set_palette,
+	/* NEW STOUGH, 2021-04-01 */
+#ifdef CONFIG_FRAMEBUFFER_CONSOLE_SOFT_SCROLLBACK
+	.con_scrolldelta	= concon_scrolldelta,
+#endif
+	/* END OF NEW STOUGH */
 	.con_set_origin 	= fbcon_set_origin,
 	.con_invert_region 	= fbcon_invert_region,
 	.con_screen_pos 	= fbcon_screen_pos,
--- include/linux/vt_kern.h.orig	2021-04-02 20:01:19.552159645 +0000
+++ include/linux/vt_kern.h	2021-04-01 17:31:45.125471834 +0000
@@ -129,6 +129,11 @@
 /* vt.c */
 void vt_event_post(unsigned int event, unsigned int old, unsigned int new);
 int vt_waitactive(int n);
+/* NEW STOUGH, 2021-04-01 */
+#ifdef CONFIG_FRAMEBUFFER_CONSOLE_SOFT_SCROLLBACK
+void concon_scrolldelta(struct vc_data *vc, int lines);
+#endif
+/* END OF NEW STOUGH */
 void change_console(struct vc_data *new_vc);
 void reset_vc(struct vc_data *vc);
 extern int do_unbind_con_driver(const struct consw *csw, int first, int last,

  reply	other threads:[~2021-04-06 14:33 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-04-05 17:12 [gentoo-user] Console scrollback is back again! Alan Mackenzie
2021-04-05 17:44 ` antlists
2021-04-05 18:13   ` Alan Mackenzie
2021-04-05 23:08     ` Michael Jones
2021-04-06  9:54       ` Alan Mackenzie
2021-04-06 15:30         ` Michael Jones
2021-04-06 13:14     ` Peter Humphrey
2021-04-06 14:13       ` John Covici
2021-04-06 14:32         ` Alan Mackenzie [this message]
2021-04-05 18:38 ` Jorge Almeida
2021-04-06  9:55   ` Alan Mackenzie
2021-04-06 10:36     ` Jorge Almeida
2021-04-05 19:58 ` karl
2021-04-06 11:04   ` Alan Mackenzie
2021-04-06  0:10 ` konsolebox
2021-04-06 12:50 ` J. Roeleveld
2021-04-08 18:16 ` konsolebox
2021-07-15 19:19 ` Alan Mackenzie

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=YGxxDrbCw2ueEdUe@ACM \
    --to=acm@muc.de \
    --cc=gentoo-user@lists.gentoo.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox