Re: [PATCH] vt: add support for smput/rmput escape codes
From: Jiri Slaby
Date: Mon Aug 25 2025 - 01:47:23 EST
Hi,
On 24. 08. 25, 16:20, Calixte Pernot wrote:
Support "\e[?1049h" and "\e[?1049l" escape codes.
This patch allows programs to enter and leave alternate screens.
This feature is widely available in graphical terminal emulators and mostly
used by fullscreen terminal-based user interfaces such as text editors.
Most editors such as vim and nano assume this escape code in not supported
and will not try to print the escape sequence if TERM=linux.
To try out this patch, run `TERM=xterm-256color vim` inside a VT.
Signed-off-by: Calixte Pernot <calixte.pernot@xxxxxxxxxxxxxxxx>
...
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
...
@@ -1878,6 +1883,46 @@ static int get_bracketed_paste(struct tty_struct *tty)
return vc->vc_bracketed_paste;
}
+/* console_lock is held */
+static void enter_alt_screen(struct vc_data *vc)
+{
+ unsigned int size = vc->vc_rows * vc->vc_cols * 2;
+
+ if (vc->vc_saved_screen != NULL)
+ return; /* Already inside an alt-screen */
All this is protected by console_lock, right?
+ vc->vc_saved_screen = kzalloc(size, GFP_NOWAIT);
Why GFP_NOWAIT?
+ if (vc->vc_saved_screen == NULL)
+ return;
+ memcpy(vc->vc_saved_screen, (u16 *)vc->vc_origin, size);
kmemdup();
+ vc->vc_saved_rows = vc->vc_rows;
+ vc->vc_saved_cols = vc->vc_cols;
+ save_cur(vc);
+ /* clear entire screen */
+ csi_J(vc, CSI_J_FULL);
+}
+
+/* console_lock is held */
+static void leave_alt_screen(struct vc_data *vc)
+{
+ unsigned int rows = min(vc->vc_saved_rows, vc->vc_rows);
+ unsigned int cols = min(vc->vc_saved_cols, vc->vc_cols);
+ unsigned short *src, *dest;
u16
+
+ if (vc->vc_saved_screen == NULL)
+ return; /* Not inside an alt-screen */
+ for (int r = 0; r < rows; r++) {
unsigned
+ src = vc->vc_saved_screen + r * vc->vc_saved_cols;
+ dest = ((u16 *)vc->vc_origin) + r * vc->vc_cols;
+ memcpy(dest, src, 2 * cols);
+ }
+ restore_cur(vc);
+ /* Update the entire screen */
+ if (con_should_update(vc))
+ do_update_region(vc, vc->vc_origin, vc->vc_screenbuf_size / 2);
+ kfree(vc->vc_saved_screen);
+ vc->vc_saved_screen = NULL;
+}
...
--- a/include/linux/console_struct.h
+++ b/include/linux/console_struct.h
@@ -159,6 +159,9 @@ struct vc_data {
struct uni_pagedict *uni_pagedict;
struct uni_pagedict **uni_pagedict_loc; /* [!] Location of uni_pagedict variable for this console */
u32 **vc_uni_lines; /* unicode screen content */
+ unsigned short *vc_saved_screen;
u16 *
+ unsigned int vc_saved_cols;
+ unsigned int vc_saved_rows;
/* additional information is in vt_kern.h */
};
thanks,
--
js
suse labs