From: Alan Mackenzie <acm@muc.de>
To: gentoo-user@lists.gentoo.org
Subject: Re: [gentoo-user] Console scrollback is back again!
Date: Thu, 15 Jul 2021 19:19:20 +0000 [thread overview]
Message-ID: <YPCKOJ/JoIUuIYfF@ACM> (raw)
In-Reply-To: <YGtE58CwgmkxvFQb@ACM>
[-- Attachment #1: Type: text/plain, Size: 3295 bytes --]
Hello, Gentoo.
A new kernel, gentoo-sources-5.10.49-r1 has become current.
For those who wish to have console soft scrolling, the patch which worked
with 5.10.27 actually still works in 5.10.49-r1. But I've tidied that
patch up somewhat for 5.10.49-r1 and have attached the patch file to this
post.
The instructions for using it are basically unchanged, apart from file
names, etc. Updating those instructions gives us:
(i) Extract the attached patch file to your
/usr/src/linux-5.10.49-gentoo-r1 directory (or probably any 5.10
kernel's).
(ii) From that directory run $ patch -p0 < 5.10.49-scroll.20210715.diff.
(iii)(a) If you've already got a working 5.10.49-r1, 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.49-r1, 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!
As before, it works for me, and there's nothing malicious in it, but if
it breaks for you, I'm sorry but I won't be responsible.
--
Alan Mackenzie (Nuremberg, Germany).
On Mon, Apr 05, 2021 at 17:12:07 +0000, Alan Mackenzie wrote:
> 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: 5.10.49-scroll.20210715.diff --]
[-- Type: text/plain, Size: 19113 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,9 @@
/* vt.c */
void vt_event_post(unsigned int event, unsigned int old, unsigned int new);
int vt_waitactive(int n);
+#ifdef CONFIG_FRAMEBUFFER_CONSOLE_SOFT_SCROLLBACK
+void concon_scrolldelta(struct vc_data *vc, int lines);
+#endif
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,17 @@
unsigned short *vc_screenbuf; /* In-memory character/attribute buffer */
unsigned int vc_screenbuf_size;
unsigned char vc_mode; /* KD_TEXT, ... */
+#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. */
+ unsigned short vc_char_at_pos; /* Char at vc_pos when no soft scroll */
+#endif
/* 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,9 @@
.con_font_default = fbcon_set_def_font,
.con_font_copy = fbcon_copy_font,
.con_set_palette = fbcon_set_palette,
+#ifdef CONFIG_FRAMEBUFFER_CONSOLE_SOFT_SCROLLBACK
+ .con_scrolldelta = concon_scrolldelta,
+#endif
.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,11 @@
#define DEFAULT_BELL_DURATION (HZ/8)
#define DEFAULT_CURSOR_BLINK_MS 200
+#ifdef CONFIG_FRAMEBUFFER_CONSOLE_SOFT_SCROLLBACK
+static unsigned int console_soft_scrollback_size =
+ 1024 * CONFIG_FRAMEBUFFER_CONSOLE_SOFT_SCROLLBACK_SIZE;
+#endif
+
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,218 @@
}
}
+#ifdef CONFIG_FRAMEBUFFER_CONSOLE_SOFT_SCROLLBACK
+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;
+ }
+ 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;
+}
+
+#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;
+
+ if (!vc->vc_softback_lines)
+ vc->vc_char_at_pos = scr_readw((u16 *)vc->vc_pos);
+
+ 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;
+ /* 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);
+ 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);
+ /* 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);
+ }
+ 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;
+ }
+}
+
+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);
+ if (!vc->vc_softback_lines)
+ vc->vc_sw->con_cursor(vc, CM_DRAW /* | CM_SOFTBACK */);
+ }
+}
+
+#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,10 @@
nr = b - t - 1;
if (b > vc->vc_rows || t >= b || nr < 1)
return;
+#ifdef CONFIG_FRAMEBUFFER_CONSOLE_SOFT_SCROLLBACK
+ if (dir == SM_UP && vc->vc_softback_top)
+ con_softback_note (vc, t, nr);
+#endif
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,56 @@
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;
+
+ 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;
+ p = (u16 *) start;
+ offset = (start - origin) / 2;
+ xx = offset % vc->vc_cols;
+ yy = offset / vc->vc_cols;
+ 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);
+ 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;
+ if (!count)
+ break;
+ xx = 0;
+ yy++;
+ /* if (vc->vc_sw->con_getxy) { */
+ /* p = (u16 *)start; */
+ /* start = vc->vc_sw->con_getxy(vc, start, NULL, NULL); */
+ /* } */
+ }
+}
+#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,10 @@
if (con_should_update(vc)) {
hide_cursor(vc);
do_update_region(vc, start, count);
- set_cursor(vc);
+#ifdef CONFIG_FRAMEBUFFER_CONSOLE_SOFT_SCROLLBACK
+ if (!vc->vc_softback_lines)
+#endif
+ set_cursor(vc);
}
}
@@ -927,8 +1238,17 @@
WARN_CONSOLE_UNLOCKED();
if (!con_is_visible(vc) ||
+#ifdef CONFIG_FRAMEBUFFER_CONSOLE_SOFT_SCROLLBACK
+ (
+ !concon_set_origin (vc) &&
+ (
+#endif
!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,6 @@
hide_cursor(old_vc);
if (!con_is_visible(old_vc)) {
save_screen(old_vc);
- set_origin(old_vc);
}
if (tty0dev)
sysfs_notify(&tty0dev->kobj, NULL, "active");
@@ -1017,7 +1341,6 @@
int update;
int old_was_color = vc->vc_can_do_color;
- set_origin(vc);
update = vc->vc_sw->con_switch(vc);
set_palette(vc);
/*
@@ -1032,9 +1358,19 @@
}
if (update && vc->vc_mode != KD_GRAPHICS)
- do_update_region(vc, vc->vc_origin, vc->vc_screenbuf_size / 2);
- }
- set_cursor(vc);
+ 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);
+ }
+#ifdef CONFIG_FRAMEBUFFER_CONSOLE_SOFT_SCROLLBACK
+ if (!vc->vc_softback_lines)
+#endif
+ set_cursor(vc);
if (is_switch) {
set_leds();
compute_shiftstate();
@@ -1113,12 +1455,28 @@
int err;
WARN_CONSOLE_UNLOCKED();
-
if (currcons >= MAX_NR_CONSOLES)
return -ENXIO;
if (vc_cons[currcons].d)
+ {
+#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
return 0;
+ }
/* 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,18 @@
vcs_make_sysfs(currcons);
atomic_notifier_call_chain(&vt_notifier_list, VT_ALLOCATE, ¶m);
+#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
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,12 @@
param.vc = vc;
+#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
+
while (!tty->stopped && count) {
int orig = *buf;
buf++;
@@ -3103,7 +3487,11 @@
}
if (cnt && con_is_visible(vc))
vc->vc_sw->con_putcs(vc, start, cnt, vc->state.y, start_x);
- set_cursor(vc);
+#ifdef CONFIG_FRAMEBUFFER_CONSOLE_SOFT_SCROLLBACK
+ if (!vc->vc_softback_lines)
+#endif
+ set_cursor(vc);
+
notify_update(vc);
quit:
@@ -3331,7 +3724,11 @@
/* if we race with con_close(), vt may be null */
console_lock();
vc = tty->driver_data;
- if (vc)
+ if (vc
+#ifdef CONFIG_FRAMEBUFFER_CONSOLE_SOFT_SCROLLBACK
+ && !vc->vc_softback_lines
+#endif
+ )
set_cursor(vc);
console_unlock();
}
@@ -3352,6 +3751,10 @@
vc = vc_cons[currcons].d;
+#ifdef CONFIG_FRAMEBUFFER_CONSOLE_SOFT_SCROLLBACK
+ con_update_softback(vc);
+#endif
+
/* 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,10 @@
if (console_blank_hook)
console_blank_hook(0);
set_palette(vc);
- set_cursor(vc);
+#ifdef CONFIG_FRAMEBUFFER_CONSOLE_SOFT_SCROLLBACK
+ if (!vc->vc_softback_lines)
+#endif
+ set_cursor(vc);
vt_event_post(VT_EVENT_UNBLANK, vc->vc_num, vc->vc_num);
}
EXPORT_SYMBOL(do_unblank_screen);
prev parent reply other threads:[~2021-07-15 19:19 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
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 [this message]
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=YPCKOJ/JoIUuIYfF@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