Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 27 Aug 2014 10:04:11 +0000 (UTC)
From:      Jean-Sebastien Pedron <dumbbell@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r270705 - in head/sys: dev/vt kern sys
Message-ID:  <201408271004.s7RA4B5D075878@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: dumbbell
Date: Wed Aug 27 10:04:10 2014
New Revision: 270705
URL: http://svnweb.freebsd.org/changeset/base/270705

Log:
  vt(4): Add cngrab() and cnungrab() callbacks
  
  They are used when a panic occurs or when entering a DDB session for
  instance.
  
  cngrab() forces a vt-switch to the console window, no matter if the
  original window is another terminal or an X session. However, cnungrab()
  doesn't vt-switch back to the original window currently.
  
  MFC after:	1 week

Modified:
  head/sys/dev/vt/vt.h
  head/sys/dev/vt/vt_core.c
  head/sys/kern/subr_terminal.c
  head/sys/sys/terminal.h

Modified: head/sys/dev/vt/vt.h
==============================================================================
--- head/sys/dev/vt/vt.h	Wed Aug 27 09:57:27 2014	(r270704)
+++ head/sys/dev/vt/vt.h	Wed Aug 27 10:04:10 2014	(r270705)
@@ -261,6 +261,8 @@ struct vt_window {
 	term_rect_t		 vw_draw_area;	/* (?) Drawable area. */
 	unsigned int		 vw_number;	/* (c) Window number. */
 	int			 vw_kbdmode;	/* (?) Keyboard mode. */
+	int			 vw_prev_kbdmode;/* (?) Previous mode. */
+	int			 vw_grabbed;	/* (?) Grab count. */
 	char			*vw_kbdsq;	/* Escape sequence queue*/
 	unsigned int		 vw_flags;	/* (d) Per-window flags. */
 	int			 vw_mouse_level;/* Mouse op mode. */

Modified: head/sys/dev/vt/vt_core.c
==============================================================================
--- head/sys/dev/vt/vt_core.c	Wed Aug 27 09:57:27 2014	(r270704)
+++ head/sys/dev/vt/vt_core.c	Wed Aug 27 10:04:10 2014	(r270705)
@@ -70,6 +70,9 @@ static tc_done_t	vtterm_done;
 static tc_cnprobe_t	vtterm_cnprobe;
 static tc_cngetc_t	vtterm_cngetc;
 
+static tc_cngrab_t	vtterm_cngrab;
+static tc_cnungrab_t	vtterm_cnungrab;
+
 static tc_opened_t	vtterm_opened;
 static tc_ioctl_t	vtterm_ioctl;
 static tc_mmap_t	vtterm_mmap;
@@ -86,6 +89,9 @@ const struct terminal_class vt_termclass
 	.tc_cnprobe	= vtterm_cnprobe,
 	.tc_cngetc	= vtterm_cngetc,
 
+	.tc_cngrab	= vtterm_cngrab,
+	.tc_cnungrab	= vtterm_cnungrab,
+
 	.tc_opened	= vtterm_opened,
 	.tc_ioctl	= vtterm_ioctl,
 	.tc_mmap	= vtterm_mmap,
@@ -191,6 +197,7 @@ static struct vt_window	vt_conswindow = 
 	.vw_device = &vt_consdev,
 	.vw_terminal = &vt_consterm,
 	.vw_kbdmode = K_XLATE,
+	.vw_grabbed = 0,
 };
 static struct terminal vt_consterm = {
 	.tm_class = &vt_termclass,
@@ -1202,6 +1209,64 @@ vtterm_cngetc(struct terminal *tm)
 }
 
 static void
+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 (!cold)
+		vt_window_switch(vw);
+
+	kbd = kbd_get_keyboard(vd->vd_keyboard);
+	if (kbd == NULL)
+		return;
+
+	if (vw->vw_grabbed++ > 0)
+		return;
+
+	/*
+	 * Make sure the keyboard is accessible even when the kbd device
+	 * driver is disabled.
+	 */
+	kbdd_enable(kbd);
+
+	/* We shall always use the keyboard in the XLATE mode here. */
+	vw->vw_prev_kbdmode = vw->vw_kbdmode;
+	vw->vw_kbdmode = K_XLATE;
+	(void)kbdd_ioctl(kbd, KDSKBMODE, (caddr_t)&vw->vw_kbdmode);
+
+	kbdd_poll(kbd, TRUE);
+}
+
+static void
+vtterm_cnungrab(struct terminal *tm)
+{
+	struct vt_device *vd;
+	struct vt_window *vw;
+	keyboard_t *kbd;
+
+	vw = tm->tm_softc;
+	vd = vw->vw_device;
+
+	kbd = kbd_get_keyboard(vd->vd_keyboard);
+	if (kbd == NULL)
+		return;
+
+	if (--vw->vw_grabbed > 0)
+		return;
+
+	kbdd_poll(kbd, FALSE);
+
+	vw->vw_kbdmode = vw->vw_prev_kbdmode;
+	(void)kbdd_ioctl(kbd, KDSKBMODE, (caddr_t)&vw->vw_kbdmode);
+	kbdd_disable(kbd);
+}
+
+static void
 vtterm_opened(struct terminal *tm, int opened)
 {
 	struct vt_window *vw = tm->tm_softc;

Modified: head/sys/kern/subr_terminal.c
==============================================================================
--- head/sys/kern/subr_terminal.c	Wed Aug 27 09:57:27 2014	(r270704)
+++ head/sys/kern/subr_terminal.c	Wed Aug 27 10:04:10 2014	(r270705)
@@ -476,13 +476,17 @@ termcn_cnregister(struct terminal *tm)
 static void
 termcn_cngrab(struct consdev *cp)
 {
+	struct terminal *tm = cp->cn_arg;
 
+	tm->tm_class->tc_cngrab(tm);
 }
 
 static void
 termcn_cnungrab(struct consdev *cp)
 {
+	struct terminal *tm = cp->cn_arg;
 
+	tm->tm_class->tc_cnungrab(tm);
 }
 
 static void

Modified: head/sys/sys/terminal.h
==============================================================================
--- head/sys/sys/terminal.h	Wed Aug 27 09:57:27 2014	(r270704)
+++ head/sys/sys/terminal.h	Wed Aug 27 10:04:10 2014	(r270705)
@@ -155,6 +155,9 @@ typedef void tc_done_t(struct terminal *
 typedef void tc_cnprobe_t(struct terminal *tm, struct consdev *cd);
 typedef int tc_cngetc_t(struct terminal *tm);
 
+typedef void tc_cngrab_t(struct terminal *tm);
+typedef void tc_cnungrab_t(struct terminal *tm);
+
 typedef void tc_opened_t(struct terminal *tm, int opened);
 typedef int tc_ioctl_t(struct terminal *tm, u_long cmd, caddr_t data,
     struct thread *td);
@@ -175,6 +178,10 @@ struct terminal_class {
 	tc_cnprobe_t	*tc_cnprobe;
 	tc_cngetc_t	*tc_cngetc;
 
+	/* DDB & panic handling. */
+	tc_cngrab_t	*tc_cngrab;
+	tc_cnungrab_t	*tc_cnungrab;
+
 	/* Misc. */
 	tc_opened_t	*tc_opened;
 	tc_ioctl_t	*tc_ioctl;



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