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: [gentoo-user] Console scrollback is back again!
Date: Mon, 5 Apr 2021 17:12:07 +0000	[thread overview]
Message-ID: <YGtE58CwgmkxvFQb@ACM> (raw)

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

Hello, Gentoo.

Yes, console soft scrolling is back!  That essential feature that was
stripped out of the kernel at around 5.4.x has returned!

Only this time, it's even better!  Instead of one scrollback buffer
shared between all tty's, there's now a buffer for each tty.

How to get it working:
(i) Extract the enclosed patch file to your /usr/src/linux-5.10.27-gentoo
directory (or probably any 5.10 kernel's).
(ii) From that directory run $ patch -p0 < diff.20210405.diff.
(iii)(a) If you've already got a working 5.10.27, do a $ make oldconfig.
  That should bring up the new configuration items, for which you can
  accept the defaults.  These two items are a flag to enable the
  scrollback, and a buffer size defaulting to 128kB.
(iii)(b) If you haven't yet got a 5.10.27, just configure your kernel in
  the usual way.  The two new items are under Device Drivers/Graphics
  support/Console display driver support.
(iv) Build the kernel.
(v) Put the new kernel into your usual boot manager.
(vi) Reboot and enjoy!

Admittedly, the exercise isn't quite finished - the patched source files
still have my personal change markings in them, to make debugging easier.
But the problems I reported here a few days ago are now solved.  One or
two features haven't (yet) been implemented - having a single scroll
buffer shared amongst all tty's isn't there, and there're no kernel
command line parameters to control the feature.

Also, you may wonder about how safe the patch is.  All I can say is that
there is nothing malicious in it, and I am known on this list, but of
course if it breaks I won't be to blame.

Bug reports and other comments are welcome, of course.

If anybody would like the corresponding patch which works on 5.4.n, for n
>= 80, that is available, too.

-- 
Alan Mackenzie (Nuremberg, Germany).


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

--- ./include/linux/vt_kern.h.orig	2020-12-13 22:41:30.000000000 +0000
+++ ./include/linux/vt_kern.h	2021-04-05 15:22:28.445755234 +0000
@@ -127,6 +127,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);
 int do_unbind_con_driver(const struct consw *csw, int first, int last,
--- ./include/linux/console_struct.h.orig	2020-12-13 22:41:30.000000000 +0000
+++ ./include/linux/console_struct.h	2021-04-05 15:22:28.432755234 +0000
@@ -109,6 +109,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-05 15:22:28.434755234 +0000
+++ ./drivers/video/fbdev/core/fbcon.c	2021-04-05 15:56:00.836644342 +0000
@@ -3084,6 +3084,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_invert_region 	= fbcon_invert_region,
 	.con_screen_pos 	= fbcon_screen_pos,
 	.con_getxy 		= fbcon_getxy,
--- ./drivers/video/console/Kconfig.orig	2020-12-13 22:41:30.000000000 +0000
+++ ./drivers/video/console/Kconfig	2021-04-05 15:22:28.414755235 +0000
@@ -78,6 +78,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.c.orig	2020-12-13 22:41:30.000000000 +0000
+++ ./drivers/tty/vt/vt.c	2021-04-05 16:20:32.624563241 +0000
@@ -134,6 +134,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
@@ -287,7 +294,7 @@
 		bool viewed)
 {
 	unsigned short *p;
-	
+
 	if (!viewed)
 		p = (unsigned short *)(vc->vc_origin + offset);
 	else if (!vc->vc_sw->con_screen_pos)
@@ -616,6 +623,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->state.y - 1)
+		{
+			c = scr_readw((u16 *)(s + vc->state.x));
+			scr_writew(c, (u16 *)vc->vc_pos);
+			vc->vc_sw->con_putcs
+				(vc, (u16 *)vc->vc_pos, 1, line, vc->state.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)
@@ -626,6 +859,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;
@@ -641,6 +880,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;
@@ -684,6 +989,7 @@
 		}
 	}
 }
+#endif
 
 void update_region(struct vc_data *vc, unsigned long start, int count)
 {
@@ -692,7 +998,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);
 	}
 }
 
@@ -927,8 +1238,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;
@@ -1004,7 +1326,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");
@@ -1017,7 +1341,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);
 		/*
@@ -1032,9 +1358,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();
@@ -1113,12 +1455,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
@@ -1158,6 +1520,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);
@@ -1629,7 +2005,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;
@@ -1641,7 +2017,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;
 }
 
@@ -2888,6 +3264,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;
 		buf++;
@@ -3103,7 +3487,16 @@
 	}
 	if (cnt && con_is_visible(vc))
 		vc->vc_sw->con_putcs(vc, start, cnt, vc->state.y, start_x);
-	set_cursor(vc);
+	/* OLD STOUGH, 2021-04-05 */
+	/* set_cursor(vc); */
+	/* NEW STOUGH, 2021-04-05 */
+#ifdef CONFIG_FRAMEBUFFER_CONSOLE_SOFT_SCROLLBACK
+	if (!vc->vc_softback_lines)
+#endif
+		/* END OF NEW STOUGH */
+		set_cursor(vc);
+
+	/* END OF NEW STOUGH */
 	notify_update(vc);
 
 quit:
@@ -3331,7 +3724,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();
 }
@@ -3352,6 +3751,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;
@@ -3407,7 +3812,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);
@@ -4108,7 +4513,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;
@@ -4409,7 +4814,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);

             reply	other threads:[~2021-04-05 17:12 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-04-05 17:12 Alan Mackenzie [this message]
2021-04-05 17:44 ` [gentoo-user] Console scrollback is back again! 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
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=YGtE58CwgmkxvFQb@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