Index: sys/dev/vt/colors/vt_termcolors.h =================================================================== --- sys/dev/vt/colors/vt_termcolors.h +++ sys/dev/vt/colors/vt_termcolors.h @@ -46,7 +46,18 @@ COLOR_FORMAT_MAX = 15, }; +#define NCOLORS 16 + +/* + * Between console's palette and VGA's one: + * - blue and red are swapped (1 <-> 4) + * - yellow and cyan are swapped (3 <-> 6) + */ +static const int cons_to_vga_colors[NCOLORS] = { + 0, 4, 2, 6, 1, 5, 3, 7, + 8, 12, 10, 14, 9, 13, 11, 15 +}; + /* Helper to fill color map used by driver */ int vt_generate_cons_palette(uint32_t *palette, int format, uint32_t rmax, int roffset, uint32_t gmax, int goffset, uint32_t bmax, int boffset); - Index: sys/dev/vt/colors/vt_termcolors.c =================================================================== --- sys/dev/vt/colors/vt_termcolors.c +++ sys/dev/vt/colors/vt_termcolors.c @@ -38,8 +38,6 @@ #include <dev/vt/colors/vt_termcolors.h> -#define NCOLORS 16 - static struct { unsigned char r; /* Red percentage value. */ unsigned char g; /* Green percentage value. */ @@ -64,16 +62,6 @@ {100, 100, 100}, /* white */ }; -/* - * Between console's palette and VGA's one: - * - blue and red are swapped (1 <-> 4) - * - yellow ad cyan are swapped (3 <-> 6) - */ -static const int cons_to_vga_colors[NCOLORS] = { - 0, 4, 2, 6, 1, 5, 3, 7, - 0, 4, 2, 6, 1, 5, 3, 7 -}; - static int vt_parse_rgb_triplet(const char *rgb, unsigned char *r, unsigned char *g, unsigned char *b) @@ -171,21 +159,21 @@ { int i; - vt_palette_init(); - -#define CF(_f, _i) ((_f ## max * color_def[(_i)]._f / 100) << _f ## offset) - for (i = 0; i < NCOLORS; i++) { - switch (format) { - case COLOR_FORMAT_VGA: + switch (format) { + case COLOR_FORMAT_VGA: + for (i = 0; i < NCOLORS; i++) palette[i] = cons_to_vga_colors[i]; - break; - case COLOR_FORMAT_RGB: + break; + case COLOR_FORMAT_RGB: + vt_palette_init(); +#define CF(_f, _i) ((_f ## max * color_def[(_i)]._f / 100) << _f ## offset) + for (i = 0; i < NCOLORS; i++) palette[i] = CF(r, i) | CF(g, i) | CF(b, i); - break; - default: - return (ENODEV); - } - } #undef CF + break; + default: + return (ENODEV); + } + return (0); } Index: sys/dev/vt/hw/vga/vt_vga.c =================================================================== --- sys/dev/vt/hw/vga/vt_vga.c +++ sys/dev/vt/hw/vga/vt_vga.c @@ -43,6 +43,7 @@ #include <sys/rman.h> #include <dev/vt/vt.h> +#include <dev/vt/colors/vt_termcolors.h> #include <dev/vt/hw/vga/vt_vga_reg.h> #include <dev/pci/pcivar.h> @@ -152,7 +153,7 @@ return; REG_WRITE1(sc, VGA_GC_ADDRESS, VGA_GC_SET_RESET); - REG_WRITE1(sc, VGA_GC_DATA, color); + REG_WRITE1(sc, VGA_GC_DATA, cons_to_vga_colors[color]); sc->vga_curfg = color; } @@ -167,7 +168,7 @@ return; REG_WRITE1(sc, VGA_GC_ADDRESS, VGA_GC_SET_RESET); - REG_WRITE1(sc, VGA_GC_DATA, color); + REG_WRITE1(sc, VGA_GC_DATA, cons_to_vga_colors[color]); /* * Write 8 pixels using the background color to an off-screen @@ -888,7 +889,9 @@ ch = vga_get_cp437(TCHAR_CHARACTER(c)); /* Convert colors to VGA attributes. */ - attr = bg << 4 | fg; + attr = + cons_to_vga_colors[bg] << 4 | + cons_to_vga_colors[fg]; MEM_WRITE1(sc, (row * 80 + col) * 2 + 0, ch); @@ -1114,43 +1117,45 @@ REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_PALETTE(0)); REG_WRITE1(sc, VGA_AC_WRITE, 0); REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_PALETTE(1)); - REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_PAL_R); + REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_PAL_B); REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_PALETTE(2)); REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_PAL_G); REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_PALETTE(3)); - REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_PAL_SG | VGA_AC_PAL_R); + REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_PAL_G | VGA_AC_PAL_B); REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_PALETTE(4)); - REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_PAL_B); + REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_PAL_R); REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_PALETTE(5)); REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_PAL_R | VGA_AC_PAL_B); REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_PALETTE(6)); - REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_PAL_G | VGA_AC_PAL_B); + REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_PAL_SG | VGA_AC_PAL_R); REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_PALETTE(7)); REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_PAL_R | VGA_AC_PAL_G | VGA_AC_PAL_B); + REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_PALETTE(8)); REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_PAL_SR | VGA_AC_PAL_SG | VGA_AC_PAL_SB); REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_PALETTE(9)); REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_PAL_SR | VGA_AC_PAL_SG | - VGA_AC_PAL_SB | VGA_AC_PAL_R); + VGA_AC_PAL_SB | VGA_AC_PAL_B); REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_PALETTE(10)); REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_PAL_SR | VGA_AC_PAL_SG | VGA_AC_PAL_SB | VGA_AC_PAL_G); REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_PALETTE(11)); REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_PAL_SR | VGA_AC_PAL_SG | - VGA_AC_PAL_SB | VGA_AC_PAL_R | VGA_AC_PAL_G); + VGA_AC_PAL_SB | VGA_AC_PAL_G | VGA_AC_PAL_B); REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_PALETTE(12)); REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_PAL_SR | VGA_AC_PAL_SG | - VGA_AC_PAL_SB | VGA_AC_PAL_B); + VGA_AC_PAL_SB | VGA_AC_PAL_R); REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_PALETTE(13)); REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_PAL_SR | VGA_AC_PAL_SG | VGA_AC_PAL_SB | VGA_AC_PAL_R | VGA_AC_PAL_B); REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_PALETTE(14)); REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_PAL_SR | VGA_AC_PAL_SG | - VGA_AC_PAL_SB | VGA_AC_PAL_G | VGA_AC_PAL_B); + VGA_AC_PAL_SB | VGA_AC_PAL_R | VGA_AC_PAL_G); REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_PALETTE(15)); REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_PAL_SR | VGA_AC_PAL_SG | VGA_AC_PAL_SB | VGA_AC_PAL_R | VGA_AC_PAL_G | VGA_AC_PAL_B); + REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_OVERSCAN_COLOR); REG_WRITE1(sc, VGA_AC_WRITE, 0); REG_WRITE1(sc, VGA_AC_WRITE, VGA_AC_COLOR_PLANE_ENABLE); Index: sys/dev/vt/vt.h =================================================================== --- sys/dev/vt/vt.h +++ sys/dev/vt/vt.h @@ -172,7 +172,7 @@ #define VT_LOCK_ASSERT(vd, what) mtx_assert(&(vd)->vd_lock, what) void vt_resume(struct vt_device *vd); -void vt_resume_flush_timer(struct vt_device *vd, int ms); +void vt_resume_flush_timer(struct vt_window *vw, int ms); void vt_suspend(struct vt_device *vd); /* @@ -213,16 +213,18 @@ #define VBF_DEFAULT_HISTORY_SIZE 500 #endif -void vtbuf_copy(struct vt_buf *, const term_rect_t *, const term_pos_t *); +void vtbuf_lock(struct vt_buf *); +void vtbuf_unlock(struct vt_buf *); +void vtbuf_copy_locked(struct vt_buf *, const term_rect_t *, const term_pos_t *); void vtbuf_fill_locked(struct vt_buf *, const term_rect_t *, term_char_t); void vtbuf_init_early(struct vt_buf *); void vtbuf_init(struct vt_buf *, const term_pos_t *); void vtbuf_grow(struct vt_buf *, const term_pos_t *, unsigned int); -void vtbuf_putchar(struct vt_buf *, const term_pos_t *, term_char_t); -void vtbuf_cursor_position(struct vt_buf *, const term_pos_t *); +void vtbuf_putchar_locked(struct vt_buf *, const term_pos_t *, term_char_t); +void vtbuf_cursor_position_locked(struct vt_buf *, const term_pos_t *); void vtbuf_scroll_mode(struct vt_buf *vb, int yes); -void vtbuf_dirty(struct vt_buf *vb, const term_rect_t *area); -void vtbuf_undirty(struct vt_buf *, term_rect_t *); +void vtbuf_dirty_locked(struct vt_buf *vb, const term_rect_t *area); +void vtbuf_undirty_locked(struct vt_buf *, term_rect_t *); void vtbuf_sethistory_size(struct vt_buf *, unsigned int); int vtbuf_iscursor(const struct vt_buf *vb, int row, int col); void vtbuf_cursor_visibility(struct vt_buf *, int); Index: sys/dev/vt/vt_buf.c =================================================================== --- sys/dev/vt/vt_buf.c +++ sys/dev/vt/vt_buf.c @@ -49,6 +49,8 @@ #define VTBUF_LOCK(vb) mtx_lock_spin(&(vb)->vb_lock) #define VTBUF_UNLOCK(vb) mtx_unlock_spin(&(vb)->vb_lock) +//#define VTBUF_IS_LOCKED(vb) mtx_assert(&(vb)->vb_lock, MA_OWNED); +#define VTBUF_IS_LOCKED(vb) #define POS_INDEX(c, r) (((r) << 12) + (c)) #define POS_COPY(d, s) do { \ @@ -253,10 +255,26 @@ return (0); } -static inline void +void +vtbuf_lock(struct vt_buf *vb) +{ + + VTBUF_LOCK(vb); +} + +void +vtbuf_unlock(struct vt_buf *vb) +{ + + VTBUF_UNLOCK(vb); +} + +void vtbuf_dirty_locked(struct vt_buf *vb, const term_rect_t *area) { + VTBUF_IS_LOCKED(vb); + if (vb->vb_dirtyrect.tr_begin.tp_row > area->tr_begin.tp_row) vb->vb_dirtyrect.tr_begin.tp_row = area->tr_begin.tp_row; if (vb->vb_dirtyrect.tr_begin.tp_col > area->tr_begin.tp_col) @@ -267,15 +285,6 @@ vb->vb_dirtyrect.tr_end.tp_col = area->tr_end.tp_col; } -void -vtbuf_dirty(struct vt_buf *vb, const term_rect_t *area) -{ - - VTBUF_LOCK(vb); - vtbuf_dirty_locked(vb, area); - VTBUF_UNLOCK(vb); -} - static inline void vtbuf_dirty_cell_locked(struct vt_buf *vb, const term_pos_t *p) { @@ -296,23 +305,25 @@ } void -vtbuf_undirty(struct vt_buf *vb, term_rect_t *r) +vtbuf_undirty_locked(struct vt_buf *vb, term_rect_t *r) { - VTBUF_LOCK(vb); + VTBUF_IS_LOCKED(vb); + *r = vb->vb_dirtyrect; vtbuf_make_undirty(vb); - VTBUF_UNLOCK(vb); } void -vtbuf_copy(struct vt_buf *vb, const term_rect_t *r, const term_pos_t *p2) +vtbuf_copy_locked(struct vt_buf *vb, const term_rect_t *r, const term_pos_t *p2) { const term_pos_t *p1 = &r->tr_begin; term_rect_t area; unsigned int rows, cols; int pr, rdiff; + VTBUF_IS_LOCKED(vb); + KASSERT(r->tr_begin.tp_row < vb->vb_scr_size.tp_row, ("vtbuf_copy begin.tp_row %d must be less than screen width %d", r->tr_begin.tp_row, vb->vb_scr_size.tp_row)); @@ -362,11 +373,11 @@ area.tr_begin = *p2; area.tr_end.tp_row = MIN(p2->tp_row + rows, vb->vb_scr_size.tp_row); area.tr_end.tp_col = MIN(p2->tp_col + cols, vb->vb_scr_size.tp_col); - vtbuf_dirty(vb, &area); + vtbuf_dirty_locked(vb, &area); } static void -vtbuf_fill(struct vt_buf *vb, const term_rect_t *r, term_char_t c) +vtbuf_do_fill(struct vt_buf *vb, const term_rect_t *r, term_char_t c) { unsigned int pr, pc; term_char_t *row; @@ -383,6 +394,9 @@ void vtbuf_fill_locked(struct vt_buf *vb, const term_rect_t *r, term_char_t c) { + + VTBUF_IS_LOCKED(vb); + KASSERT(r->tr_begin.tp_row < vb->vb_scr_size.tp_row, ("vtbuf_fill_locked begin.tp_row %d must be < screen height %d", r->tr_begin.tp_row, vb->vb_scr_size.tp_row)); @@ -397,10 +411,9 @@ ("vtbuf_fill_locked end.tp_col %d must be <= screen width %d", r->tr_end.tp_col, vb->vb_scr_size.tp_col)); - VTBUF_LOCK(vb); - vtbuf_fill(vb, r, c); + vtbuf_do_fill(vb, r, c); + vtbuf_dirty_locked(vb, r); - VTBUF_UNLOCK(vb); } static void @@ -431,7 +444,7 @@ rect.tr_begin.tp_row = rect.tr_begin.tp_col = 0; rect.tr_end.tp_col = vb->vb_scr_size.tp_col; rect.tr_end.tp_row = vb->vb_history_size; - vtbuf_fill(vb, &rect, VTBUF_SPACE_CHAR(TERMINAL_NORM_ATTR)); + vtbuf_do_fill(vb, &rect, VTBUF_SPACE_CHAR(TERMINAL_NORM_ATTR)); vtbuf_make_undirty(vb); if ((vb->vb_flags & VBF_MTX_INIT) == 0) { mtx_init(&vb->vb_lock, "vtbuf", NULL, MTX_SPIN); @@ -631,10 +644,12 @@ } void -vtbuf_putchar(struct vt_buf *vb, const term_pos_t *p, term_char_t c) +vtbuf_putchar_locked(struct vt_buf *vb, const term_pos_t *p, term_char_t c) { term_char_t *row; + VTBUF_IS_LOCKED(vb); + KASSERT(p->tp_row < vb->vb_scr_size.tp_row, ("vtbuf_putchar tp_row %d must be less than screen width %d", p->tp_row, vb->vb_scr_size.tp_row)); @@ -645,23 +660,20 @@ row = vb->vb_rows[(vb->vb_curroffset + p->tp_row) % VTBUF_MAX_HEIGHT(vb)]; if (row[p->tp_col] != c) { - VTBUF_LOCK(vb); row[p->tp_col] = c; vtbuf_dirty_cell_locked(vb, p); - VTBUF_UNLOCK(vb); } } void -vtbuf_cursor_position(struct vt_buf *vb, const term_pos_t *p) +vtbuf_cursor_position_locked(struct vt_buf *vb, const term_pos_t *p) { + VTBUF_IS_LOCKED(vb); if (vb->vb_flags & VBF_CURSOR) { - VTBUF_LOCK(vb); vtbuf_dirty_cell_locked(vb, &vb->vb_cursor); vb->vb_cursor = *p; vtbuf_dirty_cell_locked(vb, &vb->vb_cursor); - VTBUF_UNLOCK(vb); } else { vb->vb_cursor = *p; } @@ -687,7 +699,9 @@ area.tr_end.tp_col = vb->vb_scr_size.tp_col; area.tr_end.tp_row = MAX(s, e) + 1; - vtbuf_dirty(vb, &area); + vtbuf_lock(vb); + vtbuf_dirty_locked(vb, &area); + vtbuf_unlock(vb); } } @@ -853,4 +867,3 @@ vtbuf_dirty_cell_locked(vb, &vb->vb_cursor); VTBUF_UNLOCK(vb); } - Index: sys/dev/vt/vt_core.c =================================================================== --- sys/dev/vt/vt_core.c +++ sys/dev/vt/vt_core.c @@ -61,6 +61,7 @@ #include <machine/frame.h> #endif +static tc_prepare_t vtterm_prepare; static tc_bell_t vtterm_bell; static tc_cursor_t vtterm_cursor; static tc_putchar_t vtterm_putchar; @@ -80,6 +81,7 @@ static tc_mmap_t vtterm_mmap; const struct terminal_class vt_termclass = { + .tc_prepare = vtterm_prepare, .tc_bell = vtterm_bell, .tc_cursor = vtterm_cursor, .tc_putchar = vtterm_putchar, @@ -285,8 +287,12 @@ } void -vt_resume_flush_timer(struct vt_device *vd, int ms) +vt_resume_flush_timer(struct vt_window *vw, int ms) { + struct vt_device *vd = vw->vw_device; + + if (vd->vd_curwindow != vw) + return; if (!(vd->vd_flags & VDF_ASYNC) || !atomic_cmpset_int(&vd->vd_timer_armed, 0, 1)) @@ -531,14 +537,14 @@ return (0); if (!(vw->vw_flags & (VWF_OPENED|VWF_CONSOLE))) return (EINVAL); - + vd->vd_curwindow = vw; vd->vd_flags |= VDF_INVALID; if (vd->vd_driver->vd_postswitch) vd->vd_driver->vd_postswitch(vd); return (0); } - + VT_LOCK(vd); if (curvw == vw) { /* Nothing to do. */ @@ -560,7 +566,7 @@ if (vd->vd_driver->vd_postswitch) vd->vd_driver->vd_postswitch(vd); - vt_resume_flush_timer(vd, 0); + vt_resume_flush_timer(vw, 0); /* Restore per-window keyboard mode. */ mtx_lock(&Giant); @@ -680,7 +686,7 @@ diff = vthistory_seek(&vw->vw_buf, offset, whence); if (diff) vw->vw_device->vd_flags |= VDF_INVALID; - vt_resume_flush_timer(vw->vw_device, 0); + vt_resume_flush_timer(vw, 0); } static int @@ -1035,8 +1041,7 @@ { struct vt_window *vw = tm->tm_softc; - vtbuf_cursor_position(&vw->vw_buf, p); - vt_resume_flush_timer(vw->vw_device, 0); + vtbuf_cursor_position_locked(&vw->vw_buf, p); } static void @@ -1044,8 +1049,7 @@ { struct vt_window *vw = tm->tm_softc; - vtbuf_putchar(&vw->vw_buf, p, c); - vt_resume_flush_timer(vw->vw_device, 0); + vtbuf_putchar_locked(&vw->vw_buf, p, c); } static void @@ -1054,7 +1058,6 @@ struct vt_window *vw = tm->tm_softc; vtbuf_fill_locked(&vw->vw_buf, r, c); - vt_resume_flush_timer(vw->vw_device, 0); } static void @@ -1063,8 +1066,7 @@ { struct vt_window *vw = tm->tm_softc; - vtbuf_copy(&vw->vw_buf, r, p); - vt_resume_flush_timer(vw->vw_device, 0); + vtbuf_copy_locked(&vw->vw_buf, r, p); } static void @@ -1084,7 +1086,7 @@ /* FALLTHROUGH */ case TP_SHOWCURSOR: vtbuf_cursor_visibility(&vw->vw_buf, arg); - vt_resume_flush_timer(vw->vw_device, 0); + vt_resume_flush_timer(vw, 0); break; case TP_MOUSE: vw->vw_mouse_level = arg; @@ -1142,7 +1144,7 @@ } static void -vt_mark_mouse_position_as_dirty(struct vt_device *vd) +vt_mark_mouse_position_as_dirty(struct vt_device *vd, int locked) { term_rect_t area; struct vt_window *vw; @@ -1175,7 +1177,11 @@ area.tr_end.tp_row = y + 2; } - vtbuf_dirty(&vw->vw_buf, &area); + if (!locked) + vtbuf_lock(&vw->vw_buf); + vtbuf_dirty_locked(&vw->vw_buf, &area); + if (!locked) + vtbuf_unlock(&vw->vw_buf); } #endif @@ -1230,6 +1236,8 @@ if (((vd->vd_flags & VDF_TEXTMODE) == 0) && (vf == NULL)) return (0); + vtbuf_lock(&vw->vw_buf); + #ifndef SC_NO_CUTPASTE cursor_was_shown = vd->vd_mshown; cursor_moved = (vd->vd_mx != vd->vd_mx_drawn || @@ -1250,7 +1258,7 @@ */ if (cursor_was_shown != vd->vd_mshown || (vd->vd_mshown && cursor_moved)) - vt_mark_mouse_position_as_dirty(vd); + vt_mark_mouse_position_as_dirty(vd, true); /* * Save position of the mouse cursor. It's used by backends to @@ -1265,10 +1273,10 @@ * mark the new position as dirty. */ if (vd->vd_mshown && cursor_moved) - vt_mark_mouse_position_as_dirty(vd); + vt_mark_mouse_position_as_dirty(vd, true); #endif - vtbuf_undirty(&vw->vw_buf, &tarea); + vtbuf_undirty_locked(&vw->vw_buf, &tarea); /* Force a full redraw when the screen contents are invalid. */ if (vd->vd_flags & VDF_INVALID) { @@ -1282,9 +1290,11 @@ if (tarea.tr_begin.tp_col < tarea.tr_end.tp_col) { vd->vd_driver->vd_bitblt_text(vd, vw, &tarea); + vtbuf_unlock(&vw->vw_buf); return (1); } + vtbuf_unlock(&vw->vw_buf); return (0); } @@ -1306,6 +1316,16 @@ } static void +vtterm_prepare(struct terminal *tm) +{ + struct vt_window *vw = tm->tm_softc; + + if (!kdb_active && panicstr == NULL) { + vtbuf_lock(&vw->vw_buf); + } +} + +static void vtterm_done(struct terminal *tm) { struct vt_window *vw = tm->tm_softc; @@ -1322,7 +1342,11 @@ vd->vd_flags &= ~VDF_SPLASH; vt_flush(vd); } else if (!(vd->vd_flags & VDF_ASYNC)) { + vtbuf_unlock(&vw->vw_buf); vt_flush(vd); + } else { + vtbuf_unlock(&vw->vw_buf); + vt_resume_flush_timer(vw, 0); } } @@ -1655,7 +1679,7 @@ /* Force a full redraw the next timer tick. */ if (vd->vd_curwindow == vw) { vd->vd_flags |= VDF_INVALID; - vt_resume_flush_timer(vw->vw_device, 0); + vt_resume_flush_timer(vw, 0); } vw->vw_flags &= ~VWF_BUSY; VT_UNLOCK(vd); @@ -1882,7 +1906,7 @@ vd->vd_mx / vf->vf_width, vd->vd_my / vf->vf_height); - vt_resume_flush_timer(vw->vw_device, 0); + vt_resume_flush_timer(vw, 0); return; /* Done */ case MOUSE_BUTTON_EVENT: /* Buttons */ @@ -1946,7 +1970,7 @@ * We have something marked to copy, so update pointer to * window with selection. */ - vt_resume_flush_timer(vw->vw_device, 0); + vt_resume_flush_timer(vw, 0); switch (mark) { case VTB_MARK_END: @@ -2000,8 +2024,8 @@ } /* Mark mouse position as dirty. */ - vt_mark_mouse_position_as_dirty(vd); - vt_resume_flush_timer(vw->vw_device, 0); + vt_mark_mouse_position_as_dirty(vd, false); + vt_resume_flush_timer(vw, 0); } #endif @@ -2779,7 +2803,7 @@ /* Allow to put chars now. */ terminal_mute(vd->vd_curwindow->vw_terminal, 0); /* Rerun timer for screen updates. */ - vt_resume_flush_timer(vd, 0); + vt_resume_flush_timer(vd->vd_curwindow, 0); } /* Index: sys/dev/vt/vt_cpulogos.c =================================================================== --- sys/dev/vt/vt_cpulogos.c +++ sys/dev/vt/vt_cpulogos.c @@ -194,7 +194,7 @@ if (vd->vd_curwindow == vw) { vd->vd_flags |= VDF_INVALID; - vt_resume_flush_timer(vd, 0); + vt_resume_flush_timer(vw, 0); } VT_UNLOCK(vd); } @@ -253,7 +253,7 @@ if (vd->vd_curwindow == vw) { vd->vd_flags |= VDF_INVALID; - vt_resume_flush_timer(vd, 0); + vt_resume_flush_timer(vw, 0); } callout_init(&vt_splash_cpu_callout, 1); Index: sys/kern/subr_terminal.c =================================================================== --- sys/kern/subr_terminal.c +++ sys/kern/subr_terminal.c @@ -392,17 +392,18 @@ size_t olen; unsigned int flags = 0; + TERMINAL_LOCK_TTY(tm); + if (!(tm->tm_flags & TF_MUTE)) + tm->tm_class->tc_prepare(tm); + while ((olen = ttydisc_getc(tp, obuf, sizeof obuf)) > 0) { - TERMINAL_LOCK_TTY(tm); if (!(tm->tm_flags & TF_MUTE)) { tm->tm_flags &= ~TF_BELL; teken_input(&tm->tm_emulator, obuf, olen); flags |= tm->tm_flags; } - TERMINAL_UNLOCK_TTY(tm); } - TERMINAL_LOCK_TTY(tm); if (!(tm->tm_flags & TF_MUTE)) tm->tm_class->tc_done(tm); TERMINAL_UNLOCK_TTY(tm); @@ -571,6 +572,7 @@ TERMINAL_LOCK_CONS(tm); if (!(tm->tm_flags & TF_MUTE)) { + tm->tm_class->tc_prepare(tm); backup = *teken_get_curattr(&tm->tm_emulator); teken_set_curattr(&tm->tm_emulator, &kernel_message); teken_input(&tm->tm_emulator, &cv, 1); Index: sys/sys/terminal.h =================================================================== --- sys/sys/terminal.h +++ sys/sys/terminal.h @@ -144,6 +144,7 @@ typedef teken_pos_t term_pos_t; typedef teken_rect_t term_rect_t; +typedef void tc_prepare_t(struct terminal *tm); typedef void tc_cursor_t(struct terminal *tm, const term_pos_t *p); typedef void tc_putchar_t(struct terminal *tm, const term_pos_t *p, term_char_t c); @@ -169,6 +170,7 @@ struct terminal_class { /* Terminal emulator. */ + tc_prepare_t *tc_prepare; tc_cursor_t *tc_cursor; tc_putchar_t *tc_putchar; tc_fill_t *tc_fill;