Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

vt: add support for smput/rmput escape codes

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@grenoble-inp.org>
Link: https://lore.kernel.org/r/20250825125607.2478-3-calixte.pernot@grenoble-inp.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Calixte Pernot and committed by
Greg Kroah-Hartman
23743ba6 cc4d900d

+61
+58
drivers/tty/vt/vt.c
··· 141 141 static int con_open(struct tty_struct *, struct file *); 142 142 static void vc_init(struct vc_data *vc, int do_clear); 143 143 static void gotoxy(struct vc_data *vc, int new_x, int new_y); 144 + static void restore_cur(struct vc_data *vc); 144 145 static void save_cur(struct vc_data *vc); 145 146 static void reset_terminal(struct vc_data *vc, int do_clear); 146 147 static void con_flush_chars(struct tty_struct *tty); ··· 1342 1341 kfree(vc->vc_screenbuf); 1343 1342 vc_cons[currcons].d = NULL; 1344 1343 } 1344 + if (vc->vc_saved_screen != NULL) { 1345 + kfree(vc->vc_saved_screen); 1346 + vc->vc_saved_screen = NULL; 1347 + } 1345 1348 return vc; 1346 1349 } 1347 1350 ··· 1880 1875 return vc->vc_bracketed_paste; 1881 1876 } 1882 1877 1878 + /* console_lock is held */ 1879 + static void enter_alt_screen(struct vc_data *vc) 1880 + { 1881 + unsigned int size = vc->vc_rows * vc->vc_cols * 2; 1882 + 1883 + if (vc->vc_saved_screen != NULL) 1884 + return; /* Already inside an alt-screen */ 1885 + vc->vc_saved_screen = kmemdup((u16 *)vc->vc_origin, size, GFP_KERNEL); 1886 + if (vc->vc_saved_screen == NULL) 1887 + return; 1888 + vc->vc_saved_rows = vc->vc_rows; 1889 + vc->vc_saved_cols = vc->vc_cols; 1890 + save_cur(vc); 1891 + /* clear entire screen */ 1892 + csi_J(vc, CSI_J_FULL); 1893 + } 1894 + 1895 + /* console_lock is held */ 1896 + static void leave_alt_screen(struct vc_data *vc) 1897 + { 1898 + unsigned int rows = min(vc->vc_saved_rows, vc->vc_rows); 1899 + unsigned int cols = min(vc->vc_saved_cols, vc->vc_cols); 1900 + u16 *src, *dest; 1901 + 1902 + if (vc->vc_saved_screen == NULL) 1903 + return; /* Not inside an alt-screen */ 1904 + for (unsigned int r = 0; r < rows; r++) { 1905 + src = vc->vc_saved_screen + r * vc->vc_saved_cols; 1906 + dest = ((u16 *)vc->vc_origin) + r * vc->vc_cols; 1907 + memcpy(dest, src, 2 * cols); 1908 + } 1909 + restore_cur(vc); 1910 + /* Update the entire screen */ 1911 + if (con_should_update(vc)) 1912 + do_update_region(vc, vc->vc_origin, vc->vc_screenbuf_size / 2); 1913 + kfree(vc->vc_saved_screen); 1914 + vc->vc_saved_screen = NULL; 1915 + } 1916 + 1883 1917 enum { 1884 1918 CSI_DEC_hl_CURSOR_KEYS = 1, /* CKM: cursor keys send ^[Ox/^[[x */ 1885 1919 CSI_DEC_hl_132_COLUMNS = 3, /* COLM: 80/132 mode switch */ ··· 1929 1885 CSI_DEC_hl_MOUSE_X10 = 9, 1930 1886 CSI_DEC_hl_SHOW_CURSOR = 25, /* TCEM */ 1931 1887 CSI_DEC_hl_MOUSE_VT200 = 1000, 1888 + CSI_DEC_hl_ALT_SCREEN = 1049, 1932 1889 CSI_DEC_hl_BRACKETED_PASTE = 2004, 1933 1890 }; 1934 1891 ··· 1985 1940 break; 1986 1941 case CSI_DEC_hl_BRACKETED_PASTE: 1987 1942 vc->vc_bracketed_paste = on_off; 1943 + break; 1944 + case CSI_DEC_hl_ALT_SCREEN: 1945 + if (on_off) 1946 + enter_alt_screen(vc); 1947 + else 1948 + leave_alt_screen(vc); 1988 1949 break; 1989 1950 } 1990 1951 } ··· 2229 2178 vc->vc_decawm = 1; 2230 2179 vc->vc_deccm = global_cursor_default; 2231 2180 vc->vc_decim = 0; 2181 + 2182 + if (vc->vc_saved_screen != NULL) { 2183 + kfree(vc->vc_saved_screen); 2184 + vc->vc_saved_screen = NULL; 2185 + vc->vc_saved_rows = 0; 2186 + vc->vc_saved_cols = 0; 2187 + } 2232 2188 2233 2189 vt_reset_keyboard(vc->vc_num); 2234 2190
+3
include/linux/console_struct.h
··· 159 159 struct uni_pagedict *uni_pagedict; 160 160 struct uni_pagedict **uni_pagedict_loc; /* [!] Location of uni_pagedict variable for this console */ 161 161 u32 **vc_uni_lines; /* unicode screen content */ 162 + u16 *vc_saved_screen; 163 + unsigned int vc_saved_cols; 164 + unsigned int vc_saved_rows; 162 165 /* additional information is in vt_kern.h */ 163 166 }; 164 167