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;
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "[email protected]"

Reply via email to