Commit 5eb60831 authored by Nicolas Pitre's avatar Nicolas Pitre Committed by Greg Kroah-Hartman
Browse files

vt: save/restore unicode screen buffer for alternate screen



The alternate screen support added by commit 23743ba6 ("vt: add
support for smput/rmput escape codes") only saves and restores the
regular screen buffer (vc_origin), but completely ignores the corresponding
unicode screen buffer (vc_uni_lines) creating a messed-up display.

Add vc_saved_uni_lines to save the unicode screen buffer when entering
the alternate screen, and restore it when leaving. Also ensure proper
cleanup in reset_terminal() and vc_deallocate().

Fixes: 23743ba6 ("vt: add support for smput/rmput escape codes")
Cc: stable <stable@kernel.org>
Signed-off-by: default avatarNicolas Pitre <npitre@baylibre.com>
Link: https://patch.msgid.link/5o2p6qp3-91pq-0p17-or02-1oors4417ns7@onlyvoer.pbz


Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent a7b9ce39
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -1339,6 +1339,8 @@ struct vc_data *vc_deallocate(unsigned int currcons)
			kfree(vc->vc_saved_screen);
			vc->vc_saved_screen = NULL;
		}
		vc_uniscr_free(vc->vc_saved_uni_lines);
		vc->vc_saved_uni_lines = NULL;
	}
	return vc;
}
@@ -1884,6 +1886,8 @@ static void enter_alt_screen(struct vc_data *vc)
	vc->vc_saved_screen = kmemdup((u16 *)vc->vc_origin, size, GFP_KERNEL);
	if (vc->vc_saved_screen == NULL)
		return;
	vc->vc_saved_uni_lines = vc->vc_uni_lines;
	vc->vc_uni_lines = NULL;
	vc->vc_saved_rows = vc->vc_rows;
	vc->vc_saved_cols = vc->vc_cols;
	save_cur(vc);
@@ -1905,6 +1909,8 @@ static void leave_alt_screen(struct vc_data *vc)
		dest = ((u16 *)vc->vc_origin) + r * vc->vc_cols;
		memcpy(dest, src, 2 * cols);
	}
	vc_uniscr_set(vc, vc->vc_saved_uni_lines);
	vc->vc_saved_uni_lines = NULL;
	restore_cur(vc);
	/* Update the entire screen */
	if (con_should_update(vc))
@@ -2227,6 +2233,8 @@ static void reset_terminal(struct vc_data *vc, int do_clear)
	if (vc->vc_saved_screen != NULL) {
		kfree(vc->vc_saved_screen);
		vc->vc_saved_screen = NULL;
		vc_uniscr_free(vc->vc_saved_uni_lines);
		vc->vc_saved_uni_lines = NULL;
		vc->vc_saved_rows = 0;
		vc->vc_saved_cols = 0;
	}
+1 −0
Original line number Diff line number Diff line
@@ -160,6 +160,7 @@ struct vc_data {
	struct uni_pagedict **uni_pagedict_loc; /* [!] Location of uni_pagedict variable for this console */
	u32 **vc_uni_lines;			/* unicode screen content */
	u16		*vc_saved_screen;
	u32		**vc_saved_uni_lines;
	unsigned int	vc_saved_cols;
	unsigned int	vc_saved_rows;
	/* additional information is in vt_kern.h */