Index: head/sys/dev/vt/vt.h =================================================================== --- head/sys/dev/vt/vt.h +++ head/sys/dev/vt/vt.h @@ -213,8 +213,10 @@ #define VBF_DEFAULT_HISTORY_SIZE 500 #endif +void vtbuf_lock(struct vt_buf *); +void vtbuf_unlock(struct vt_buf *); void vtbuf_copy(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_fill(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); Index: head/sys/dev/vt/vt_buf.c =================================================================== --- head/sys/dev/vt/vt_buf.c +++ head/sys/dev/vt/vt_buf.c @@ -253,10 +253,24 @@ return (0); } -static inline void -vtbuf_dirty_locked(struct vt_buf *vb, const term_rect_t *area) +void +vtbuf_lock(struct vt_buf *vb) { + VTBUF_LOCK(vb); +} + +void +vtbuf_unlock(struct vt_buf *vb) +{ + + VTBUF_UNLOCK(vb); +} + +void +vtbuf_dirty(struct vt_buf *vb, const term_rect_t *area) +{ + 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,24 +281,15 @@ 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) +vtbuf_dirty_cell(struct vt_buf *vb, const term_pos_t *p) { term_rect_t area; area.tr_begin = *p; area.tr_end.tp_row = p->tp_row + 1; area.tr_end.tp_col = p->tp_col + 1; - vtbuf_dirty_locked(vb, &area); + vtbuf_dirty(vb, &area); } static void @@ -299,10 +304,8 @@ vtbuf_undirty(struct vt_buf *vb, term_rect_t *r) { - VTBUF_LOCK(vb); *r = vb->vb_dirtyrect; vtbuf_make_undirty(vb); - VTBUF_UNLOCK(vb); } void @@ -366,7 +369,7 @@ } 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; @@ -381,26 +384,25 @@ } void -vtbuf_fill_locked(struct vt_buf *vb, const term_rect_t *r, term_char_t c) +vtbuf_fill(struct vt_buf *vb, const term_rect_t *r, term_char_t c) { + KASSERT(r->tr_begin.tp_row < vb->vb_scr_size.tp_row, - ("vtbuf_fill_locked begin.tp_row %d must be < screen height %d", + ("vtbuf_fill begin.tp_row %d must be < screen height %d", r->tr_begin.tp_row, vb->vb_scr_size.tp_row)); KASSERT(r->tr_begin.tp_col < vb->vb_scr_size.tp_col, - ("vtbuf_fill_locked begin.tp_col %d must be < screen width %d", + ("vtbuf_fill begin.tp_col %d must be < screen width %d", r->tr_begin.tp_col, vb->vb_scr_size.tp_col)); KASSERT(r->tr_end.tp_row <= vb->vb_scr_size.tp_row, - ("vtbuf_fill_locked end.tp_row %d must be <= screen height %d", + ("vtbuf_fill end.tp_row %d must be <= screen height %d", r->tr_end.tp_row, vb->vb_scr_size.tp_row)); KASSERT(r->tr_end.tp_col <= vb->vb_scr_size.tp_col, - ("vtbuf_fill_locked end.tp_col %d must be <= screen width %d", + ("vtbuf_fill 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_dirty_locked(vb, r); - VTBUF_UNLOCK(vb); + vtbuf_do_fill(vb, r, c); + vtbuf_dirty(vb, r); } static void @@ -431,7 +433,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); @@ -645,23 +647,18 @@ 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); + vtbuf_dirty_cell(vb, p); } } void vtbuf_cursor_position(struct vt_buf *vb, const term_pos_t *p) { - if (vb->vb_flags & VBF_CURSOR) { - VTBUF_LOCK(vb); - vtbuf_dirty_cell_locked(vb, &vb->vb_cursor); + vtbuf_dirty_cell(vb, &vb->vb_cursor); vb->vb_cursor = *p; - vtbuf_dirty_cell_locked(vb, &vb->vb_cursor); - VTBUF_UNLOCK(vb); + vtbuf_dirty_cell(vb, &vb->vb_cursor); } else { vb->vb_cursor = *p; } @@ -687,7 +684,9 @@ area.tr_end.tp_col = vb->vb_scr_size.tp_col; area.tr_end.tp_row = MAX(s, e) + 1; + VTBUF_LOCK(vb); vtbuf_dirty(vb, &area); + VTBUF_UNLOCK(vb); } } @@ -823,7 +822,6 @@ { int oflags, nflags; - VTBUF_LOCK(vb); oflags = vb->vb_flags; if (yes) vb->vb_flags |= VBF_CURSOR; @@ -832,8 +830,7 @@ nflags = vb->vb_flags; if (oflags != nflags) - vtbuf_dirty_cell_locked(vb, &vb->vb_cursor); - VTBUF_UNLOCK(vb); + vtbuf_dirty_cell(vb, &vb->vb_cursor); } void @@ -850,7 +847,6 @@ nflags = vb->vb_flags; if (oflags != nflags) - vtbuf_dirty_cell_locked(vb, &vb->vb_cursor); + vtbuf_dirty_cell(vb, &vb->vb_cursor); VTBUF_UNLOCK(vb); } - Index: head/sys/dev/vt/vt_core.c =================================================================== --- head/sys/dev/vt/vt_core.c +++ head/sys/dev/vt/vt_core.c @@ -66,6 +66,8 @@ static tc_putchar_t vtterm_putchar; static tc_fill_t vtterm_fill; static tc_copy_t vtterm_copy; +static tc_pre_input_t vtterm_pre_input; +static tc_post_input_t vtterm_post_input; static tc_param_t vtterm_param; static tc_done_t vtterm_done; @@ -85,6 +87,8 @@ .tc_putchar = vtterm_putchar, .tc_fill = vtterm_fill, .tc_copy = vtterm_copy, + .tc_pre_input = vtterm_pre_input, + .tc_post_input = vtterm_post_input, .tc_param = vtterm_param, .tc_done = vtterm_done, @@ -1053,7 +1057,7 @@ { struct vt_window *vw = tm->tm_softc; - vtbuf_fill_locked(&vw->vw_buf, r, c); + vtbuf_fill(&vw->vw_buf, r, c); vt_resume_flush_timer(vw->vw_device, 0); } @@ -1142,7 +1146,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 +1179,11 @@ area.tr_end.tp_row = y + 2; } + if (!locked) + vtbuf_lock(&vw->vw_buf); vtbuf_dirty(&vw->vw_buf, &area); + if (!locked) + vtbuf_unlock(&vw->vw_buf); } #endif @@ -1230,6 +1238,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 +1260,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,7 +1275,7 @@ * 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); @@ -1282,9 +1292,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 +1318,23 @@ } static void +vtterm_pre_input(struct terminal *tm) +{ + struct vt_window *vw = tm->tm_softc; + + vtbuf_lock(&vw->vw_buf); +} + +static void +vtterm_post_input(struct terminal *tm) +{ + struct vt_window *vw = tm->tm_softc; + + vtbuf_unlock(&vw->vw_buf); + vt_resume_flush_timer(vw->vw_device, 0); +} + +static void vtterm_done(struct terminal *tm) { struct vt_window *vw = tm->tm_softc; @@ -2000,7 +2029,7 @@ } /* Mark mouse position as dirty. */ - vt_mark_mouse_position_as_dirty(vd); + vt_mark_mouse_position_as_dirty(vd, false); vt_resume_flush_timer(vw->vw_device, 0); } #endif Index: head/sys/kern/subr_terminal.c =================================================================== --- head/sys/kern/subr_terminal.c +++ head/sys/kern/subr_terminal.c @@ -106,6 +106,8 @@ static tf_putchar_t termteken_putchar; static tf_fill_t termteken_fill; static tf_copy_t termteken_copy; +static tf_pre_input_t termteken_pre_input; +static tf_post_input_t termteken_post_input; static tf_param_t termteken_param; static tf_respond_t termteken_respond; @@ -115,6 +117,8 @@ .tf_putchar = termteken_putchar, .tf_fill = termteken_fill, .tf_copy = termteken_copy, + .tf_pre_input = termteken_pre_input, + .tf_post_input = termteken_post_input, .tf_param = termteken_param, .tf_respond = termteken_respond, }; @@ -624,6 +628,22 @@ struct terminal *tm = softc; tm->tm_class->tc_copy(tm, r, p); +} + +static void +termteken_pre_input(void *softc) +{ + struct terminal *tm = softc; + + tm->tm_class->tc_pre_input(tm); +} + +static void +termteken_post_input(void *softc) +{ + struct terminal *tm = softc; + + tm->tm_class->tc_post_input(tm); } static void Index: head/sys/sys/terminal.h =================================================================== --- head/sys/sys/terminal.h +++ head/sys/sys/terminal.h @@ -151,6 +151,8 @@ term_char_t c); typedef void tc_copy_t(struct terminal *tm, const term_rect_t *r, const term_pos_t *p); +typedef void tc_pre_input_t(struct terminal *tm); +typedef void tc_post_input_t(struct terminal *tm); typedef void tc_param_t(struct terminal *tm, int cmd, unsigned int arg); typedef void tc_done_t(struct terminal *tm); @@ -173,6 +175,8 @@ tc_putchar_t *tc_putchar; tc_fill_t *tc_fill; tc_copy_t *tc_copy; + tc_pre_input_t *tc_pre_input; + tc_post_input_t *tc_post_input; tc_param_t *tc_param; tc_done_t *tc_done; Index: head/sys/teken/teken.h =================================================================== --- head/sys/teken/teken.h +++ head/sys/teken/teken.h @@ -93,6 +93,8 @@ typedef void tf_fill_t(void *, const teken_rect_t *, teken_char_t, const teken_attr_t *); typedef void tf_copy_t(void *, const teken_rect_t *, const teken_pos_t *); +typedef void tf_pre_input_t(void *); +typedef void tf_post_input_t(void *); typedef void tf_param_t(void *, int, unsigned int); #define TP_SHOWCURSOR 0 #define TP_KEYPADAPP 1 @@ -114,6 +116,8 @@ tf_putchar_t *tf_putchar; tf_fill_t *tf_fill; tf_copy_t *tf_copy; + tf_pre_input_t *tf_pre_input; + tf_post_input_t *tf_post_input; tf_param_t *tf_param; tf_respond_t *tf_respond; } teken_funcs_t; Index: head/sys/teken/teken.c =================================================================== --- head/sys/teken/teken.c +++ head/sys/teken/teken.c @@ -133,6 +133,22 @@ } static inline void +teken_funcs_pre_input(const teken_t *t) +{ + + teken_assert(t->t_funcs->tf_pre_input != NULL); + t->t_funcs->tf_pre_input(t->t_softc); +} + +static inline void +teken_funcs_post_input(const teken_t *t) +{ + + teken_assert(t->t_funcs->tf_post_input != NULL); + t->t_funcs->tf_post_input(t->t_softc); +} + +static inline void teken_funcs_param(const teken_t *t, int cmd, unsigned int value) { @@ -292,8 +308,10 @@ { const char *c = buf; + teken_funcs_pre_input(t); while (len-- > 0) teken_input_byte(t, *c++); + teken_funcs_post_input(t); } const teken_pos_t *