Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 31 Dec 2020 17:10:18 GMT
From:      Kyle Evans <kevans@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: be4663433724 - main - vt: more carefully handle vt_allocate_keyboard grab work
Message-ID:  <202012311710.0BVHAIOI086982@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch main has been updated by kevans:

URL: https://cgit.FreeBSD.org/src/commit/?id=be46634337248029333a434c235c8424279b30b4

commit be46634337248029333a434c235c8424279b30b4
Author:     Kyle Evans <kevans@FreeBSD.org>
AuthorDate: 2020-12-31 16:45:41 +0000
Commit:     Kyle Evans <kevans@FreeBSD.org>
CommitDate: 2020-12-31 17:10:11 +0000

    vt: more carefully handle vt_allocate_keyboard grab work
    
    vt_allocate_keyboard only needs to unwind the effects of keyboard-grabbing,
    rather than any associated vt window action that may have also happened.
    
    Split out the bits that do the keyboard work into *_noswitch equivalents,
    and use those in keyboard allocation. This will be less error-prone when a
    later change will offer up different window state behavior when the console
    is ungrabbed.
    
    Reviewed by:    ray
    Differential Revision:  https://reviews.freebsd.org/D27110
---
 sys/dev/vt/vt_core.c | 79 ++++++++++++++++++++++++++++++++++++----------------
 1 file changed, 55 insertions(+), 24 deletions(-)

diff --git a/sys/dev/vt/vt_core.c b/sys/dev/vt/vt_core.c
index f840f7ba37f6..c273b703de93 100644
--- a/sys/dev/vt/vt_core.c
+++ b/sys/dev/vt/vt_core.c
@@ -63,6 +63,9 @@ __FBSDID("$FreeBSD$");
 #include <machine/frame.h>
 #endif
 
+static int vtterm_cngrab_noswitch(struct vt_device *, struct vt_window *);
+static int vtterm_cnungrab_noswitch(struct vt_device *, struct vt_window *);
+
 static tc_bell_t	vtterm_bell;
 static tc_cursor_t	vtterm_cursor;
 static tc_putchar_t	vtterm_putchar;
@@ -1030,7 +1033,7 @@ vt_allocate_keyboard(struct vt_device *vd)
 	if (vd->vd_curwindow == &vt_conswindow) {
 		grabbed = vd->vd_curwindow->vw_grabbed;
 		for (i = 0; i < grabbed; ++i)
-			vtterm_cnungrab(vd->vd_curwindow->vw_terminal);
+			vtterm_cnungrab_noswitch(vd, vd->vd_curwindow);
 	}
 
 	idx0 = kbd_allocate("kbdmux", -1, vd, vt_kbdevent, vd);
@@ -1068,7 +1071,7 @@ vt_allocate_keyboard(struct vt_device *vd)
 
 	if (vd->vd_curwindow == &vt_conswindow) {
 		for (i = 0; i < grabbed; ++i)
-			vtterm_cngrab(vd->vd_curwindow->vw_terminal);
+			vtterm_cngrab_noswitch(vd, vd->vd_curwindow);
 	}
 
 	return (idx0);
@@ -1740,24 +1743,24 @@ vtterm_cngetc(struct terminal *tm)
 	return (-1);
 }
 
-static void
-vtterm_cngrab(struct terminal *tm)
+/*
+ * These two do most of what we want to do in vtterm_cnungrab, but without
+ * actually switching windows.  This is necessary for, e.g.,
+ * vt_allocate_keyboard() to get the current keyboard into the state it needs to
+ * be in without damaging the device's window state.
+ *
+ * Both return the current grab count, though it's only used in vtterm_cnungrab.
+ */
+static int
+vtterm_cngrab_noswitch(struct vt_device *vd, struct vt_window *vw)
 {
-	struct vt_device *vd;
-	struct vt_window *vw;
 	keyboard_t *kbd;
 
-	vw = tm->tm_softc;
-	vd = vw->vw_device;
-
-	if (!cold)
-		vt_window_switch(vw);
+	if (vw->vw_grabbed++ > 0)
+		return (vw->vw_grabbed);
 
 	if ((kbd = vd->vd_keyboard) == NULL)
-		return;
-
-	if (vw->vw_grabbed++ > 0)
-		return;
+		return (1);
 
 	/*
 	 * Make sure the keyboard is accessible even when the kbd device
@@ -1771,29 +1774,57 @@ vtterm_cngrab(struct terminal *tm)
 	vt_update_kbd_mode(vw, kbd);
 
 	kbdd_poll(kbd, TRUE);
+	return (1);
+}
+
+static int
+vtterm_cnungrab_noswitch(struct vt_device *vd, struct vt_window *vw)
+{
+	keyboard_t *kbd;
+
+	if (--vw->vw_grabbed > 0)
+		return (vw->vw_grabbed);
+
+	if ((kbd = vd->vd_keyboard) == NULL)
+		return (0);
+
+	kbdd_poll(kbd, FALSE);
+
+	vw->vw_kbdmode = vw->vw_prev_kbdmode;
+	vt_update_kbd_mode(vw, kbd);
+	kbdd_disable(kbd);
+	return (0);
 }
 
 static void
-vtterm_cnungrab(struct terminal *tm)
+vtterm_cngrab(struct terminal *tm)
 {
 	struct vt_device *vd;
 	struct vt_window *vw;
-	keyboard_t *kbd;
 
 	vw = tm->tm_softc;
 	vd = vw->vw_device;
 
-	if ((kbd = vd->vd_keyboard) == NULL)
-		return;
 
-	if (--vw->vw_grabbed > 0)
+	if (!cold)
+		vt_window_switch(vw);
+
+	vtterm_cngrab_noswitch(vd, vw);
+}
+
+static void
+vtterm_cnungrab(struct terminal *tm)
+{
+	struct vt_device *vd;
+	struct vt_window *vw;
+
+	vw = tm->tm_softc;
+	vd = vw->vw_device;
+
+	if (vtterm_cnungrab_noswitch(vd, vw) != 0)
 		return;
 
-	kbdd_poll(kbd, FALSE);
 
-	vw->vw_kbdmode = vw->vw_prev_kbdmode;
-	vt_update_kbd_mode(vw, kbd);
-	kbdd_disable(kbd);
 }
 
 static void



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202012311710.0BVHAIOI086982>