git: 1181ac708936 - main - vt: Reprogram display controller on KDSETMODE KD_TEXT for active window
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Fri, 18 Sep 2026 16:31:50 UTC
The branch main has been updated by emaste:
URL: https://cgit.FreeBSD.org/src/commit/?id=1181ac708936d054e07089de7c5b3c1de11a4367
commit 1181ac708936d054e07089de7c5b3c1de11a4367
Author: Quentin Thébault <quentin.thebault@defenso.fr>
AuthorDate: 2026-07-02 14:27:10 +0000
Commit: Ed Maste <emaste@FreeBSD.org>
CommitDate: 2026-09-18 16:30:54 +0000
vt: Reprogram display controller on KDSETMODE KD_TEXT for active window
When a graphical application (X.Org display server, Wayland compositor)
calls KDSETMODE to set the active VT back to KD_TEXT, vt(4) does not
reset the CRTC to point to its framebuffer, leaving the last image of
the graphical application visible instead of the text console until the
next VT switch.
Add a call to vd_postswitch to reset the CRTC, set VDF_INVALID to force
a redraw and schedule the flush timer, like vt(4) does in
vt_window_switch().
Sponsored by: Defenso
Signed-off-by: Quentin Thébault <quentin.thebault@defenso.fr>
Reviewed by: vexeduxr
Pull request: https://github.com/freebsd/freebsd-src/pull/2308
---
sys/dev/vt/vt_core.c | 24 +++++++++++++++++++++++-
1 file changed, 23 insertions(+), 1 deletion(-)
diff --git a/sys/dev/vt/vt_core.c b/sys/dev/vt/vt_core.c
index 81487d27a6fc..040b8ea52183 100644
--- a/sys/dev/vt/vt_core.c
+++ b/sys/dev/vt/vt_core.c
@@ -2923,9 +2923,31 @@ skip_thunk:
switch (*(int *)data) {
case KD_TEXT:
case KD_TEXT1:
- case KD_PIXEL:
+ case KD_PIXEL: {
+ bool restore = false;
+ VT_LOCK(vd);
+ if ((vw->vw_flags & VWF_GRAPHICS) &&
+ vw == vd->vd_curwindow) {
+ /*
+ * When leaving graphics mode on the currently
+ * active window, reprogram the display
+ * controller back to text mode immediately.
+ * Without this, the CRTC retains the graphical
+ * state and the console stays invisible until
+ * the next VT switch.
+ */
+ restore = true;
+ vd->vd_flags |= VDF_INVALID;
+ }
+ VT_UNLOCK(vd);
+ if (restore) {
+ if (vd->vd_driver->vd_postswitch)
+ vd->vd_driver->vd_postswitch(vd);
+ vt_resume_flush_timer(vw, 0);
+ }
vw->vw_flags &= ~VWF_GRAPHICS;
break;
+ }
case KD_GRAPHICS:
vw->vw_flags |= VWF_GRAPHICS;
break;