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, ¶m);
+ /* 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 @@
¶m) == 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,
next prev parent 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