summaryrefslogtreecommitdiffstats
path: root/sys/dev/vt/vt_core.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/vt/vt_core.c')
-rw-r--r--sys/dev/vt/vt_core.c126
1 files changed, 101 insertions, 25 deletions
diff --git a/sys/dev/vt/vt_core.c b/sys/dev/vt/vt_core.c
index 0911739..3372804 100644
--- a/sys/dev/vt/vt_core.c
+++ b/sys/dev/vt/vt_core.c
@@ -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,
@@ -188,6 +194,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,
@@ -420,10 +427,16 @@ vt_compute_drawable_area(struct vt_window *vw)
struct vt_device *vd;
struct vt_font *vf;
- if (vw->vw_font == NULL)
+ vd = vw->vw_device;
+
+ if (vw->vw_font == NULL) {
+ vw->vw_draw_area.tr_begin.tp_col = 0;
+ vw->vw_draw_area.tr_begin.tp_row = 0;
+ vw->vw_draw_area.tr_end.tp_col = vd->vd_width;
+ vw->vw_draw_area.tr_end.tp_row = vd->vd_height;
return;
+ }
- vd = vw->vw_device;
vf = vw->vw_font;
/*
@@ -1211,6 +1224,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;
@@ -1228,30 +1299,40 @@ vtterm_opened(struct terminal *tm, int opened)
}
static int
-vt_set_border(struct vt_window *vw, struct vt_font *vf, term_color_t c)
+vt_set_border(struct vt_window *vw, term_color_t c)
{
struct vt_device *vd = vw->vw_device;
- int x, y, off_x, off_y;
if (vd->vd_driver->vd_drawrect == NULL)
return (ENOTSUP);
- x = vd->vd_width - 1;
- y = vd->vd_height - 1;
- off_x = vw->vw_draw_area.tr_begin.tp_col;
- off_y = vw->vw_draw_area.tr_begin.tp_row;
-
/* Top bar. */
- if (off_y > 0)
- vd->vd_driver->vd_drawrect(vd, 0, 0, x, off_y - 1, 1, c);
+ if (vw->vw_draw_area.tr_begin.tp_row > 0)
+ vd->vd_driver->vd_drawrect(vd,
+ 0, 0,
+ vd->vd_width - 1, vw->vw_draw_area.tr_begin.tp_row - 1,
+ 1, c);
+
/* Left bar. */
- if (off_x > 0)
- vd->vd_driver->vd_drawrect(vd, 0, off_y, off_x - 1, y - off_y,
+ if (vw->vw_draw_area.tr_begin.tp_col > 0)
+ vd->vd_driver->vd_drawrect(vd,
+ 0, 0,
+ vw->vw_draw_area.tr_begin.tp_col - 1, vd->vd_height - 1,
+ 1, c);
+
+ /* Right bar. */
+ if (vw->vw_draw_area.tr_end.tp_col < vd->vd_width)
+ vd->vd_driver->vd_drawrect(vd,
+ vw->vw_draw_area.tr_end.tp_col - 1, 0,
+ vd->vd_width - 1, vd->vd_height - 1,
+ 1, c);
+
+ /* Bottom bar. */
+ if (vw->vw_draw_area.tr_end.tp_row < vd->vd_height)
+ vd->vd_driver->vd_drawrect(vd,
+ 0, vw->vw_draw_area.tr_end.tp_row - 1,
+ vd->vd_width - 1, vd->vd_height - 1,
1, c);
- /* Right bar. May be 1 pixel wider than necessary due to rounding. */
- vd->vd_driver->vd_drawrect(vd, x - off_x, off_y, x, y - off_y, 1, c);
- /* Bottom bar. May be 1 mixel taller than necessary due to rounding. */
- vd->vd_driver->vd_drawrect(vd, 0, y - off_y, x, y, 1, c);
return (0);
}
@@ -1283,11 +1364,6 @@ vt_change_font(struct vt_window *vw, struct vt_font *vf)
VT_UNLOCK(vd);
return (EBUSY);
}
- if (vd->vd_flags & VDF_TEXTMODE) {
- /* Our device doesn't need fonts. */
- VT_UNLOCK(vd);
- return (ENOTTY);
- }
vw->vw_flags |= VWF_BUSY;
VT_UNLOCK(vd);
@@ -1302,7 +1378,7 @@ vt_change_font(struct vt_window *vw, struct vt_font *vf)
/* Actually apply the font to the current window. */
VT_LOCK(vd);
- if (vw->vw_font != vf) {
+ if (vw->vw_font != vf && vw->vw_font != NULL && vf != NULL) {
/*
* In case vt_change_font called to update size we don't need
* to update font link.
@@ -1325,7 +1401,7 @@ vt_change_font(struct vt_window *vw, struct vt_font *vf)
/* Force a full redraw the next timer tick. */
if (vd->vd_curwindow == vw) {
- vt_set_border(vw, vf, TC_BLACK);
+ vt_set_border(vw, TC_BLACK);
vd->vd_flags |= VDF_INVALID;
vt_resume_flush_timer(vw->vw_device, 0);
}
@@ -2247,7 +2323,6 @@ vt_allocate(struct vt_driver *drv, void *softc)
main_vd->vd_driver->vd_name, drv->vd_name);
}
vd = main_vd;
- VT_LOCK(vd);
if (vd->vd_flags & VDF_ASYNC) {
/* Stop vt_flush periodic task. */
@@ -2263,6 +2338,7 @@ vt_allocate(struct vt_driver *drv, void *softc)
* Reset VDF_TEXTMODE flag, driver who require that flag (vt_vga) will
* set it.
*/
+ VT_LOCK(vd);
vd->vd_flags &= ~VDF_TEXTMODE;
vd->vd_driver = drv;
OpenPOWER on IntegriCloud