diff options
-rw-r--r-- | sys/dev/syscons/schistory.c | 82 | ||||
-rw-r--r-- | sys/dev/syscons/scvidctl.c | 17 | ||||
-rw-r--r-- | sys/dev/syscons/syscons.c | 12 | ||||
-rw-r--r-- | sys/dev/syscons/syscons.h | 6 |
4 files changed, 88 insertions, 29 deletions
diff --git a/sys/dev/syscons/schistory.c b/sys/dev/syscons/schistory.c index 765733c..433182d 100644 --- a/sys/dev/syscons/schistory.c +++ b/sys/dev/syscons/schistory.c @@ -26,7 +26,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id:$ + * $Id: schistory.c,v 1.1 1999/06/22 14:13:26 yokota Exp $ */ #include "sc.h" @@ -68,7 +68,7 @@ static void history_to_screen(scr_stat *scp); /* allocate a history buffer */ int -sc_alloc_history_buffer(scr_stat *scp, int lines, int wait) +sc_alloc_history_buffer(scr_stat *scp, int lines, int prev_ysize, int wait) { /* * syscons unconditionally allocates buffers upto @@ -77,38 +77,82 @@ sc_alloc_history_buffer(scr_stat *scp, int lines, int wait) * subject to extra_history_size. */ sc_vtb_t *history; + sc_vtb_t *prev_history; int cur_lines; /* current buffer size */ int min_lines; /* guaranteed buffer size */ + int delta; /* lines to put back */ if (lines <= 0) lines = SC_HISTORY_SIZE; /* use the default value */ + + /* make it at least as large as the screen size */ lines = imax(lines, scp->ysize); - min_lines = imax(SC_HISTORY_SIZE, scp->ysize); - history = scp->history; + /* remove the history buffer while we update it */ + history = prev_history = scp->history; scp->history = NULL; - if (history == NULL) { - cur_lines = 0; - } else { + + /* calculate the amount of lines to put back to extra_history_size */ + delta = 0; + if (prev_history) { cur_lines = sc_vtb_rows(history); + min_lines = imax(SC_HISTORY_SIZE, prev_ysize); if (cur_lines > min_lines) - extra_history_size += cur_lines - min_lines; - sc_vtb_destroy(history); + delta = cur_lines - min_lines; } - if (lines > min_lines) - extra_history_size -= lines - min_lines; - history = (sc_vtb_t *)malloc(sizeof(*history), - M_DEVBUF, (wait) ? M_WAITOK : M_NOWAIT); - if (history != NULL) + /* lines upto min_lines are always allowed. */ + min_lines = imax(SC_HISTORY_SIZE, scp->ysize); + if (lines > min_lines) { + if (lines - min_lines > extra_history_size + delta) { + /* too many lines are requested */ + scp->history = prev_history; + return EINVAL; + } + } + + /* destroy the previous buffer and allocate a new one */ + if (prev_history == NULL) { + history = (sc_vtb_t *)malloc(sizeof(*history), + M_DEVBUF, + (wait) ? M_WAITOK : M_NOWAIT); + } else { + extra_history_size += delta; + sc_vtb_destroy(prev_history); + } + if (history != NULL) { + if (lines > min_lines) + extra_history_size -= lines - min_lines; sc_vtb_init(history, VTB_RINGBUFFER, scp->xsize, lines, NULL, wait); + } + scp->history_pos = 0; scp->history = history; return 0; } +void +sc_free_history_buffer(scr_stat *scp, int prev_ysize) +{ + sc_vtb_t *history; + int cur_lines; /* current buffer size */ + int min_lines; /* guaranteed buffer size */ + + history = scp->history; + scp->history = NULL; + if (history == NULL) + return; + + cur_lines = sc_vtb_rows(history); + min_lines = imax(SC_HISTORY_SIZE, prev_ysize); + extra_history_size += (cur_lines > min_lines) ? cur_lines - min_lines : 0; + + sc_vtb_destroy(history); + free(history, M_DEVBUF); +} + /* copy entire screen into the top of the history buffer */ void sc_hist_save(scr_stat *scp) @@ -200,6 +244,7 @@ sc_hist_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag, struct proc *p) { scr_stat *scp; + int error; switch (cmd) { @@ -209,9 +254,14 @@ sc_hist_ioctl(struct tty *tp, u_long cmd, caddr_t data, int flag, return EINVAL; if (scp->status & BUFFER_SAVED) return EBUSY; - return sc_alloc_history_buffer(scp, + DPRINTF(5, ("lines:%d, ysize:%d, pool:%d\n", + *(int *)data, scp->ysize, extra_history_size)); + error = sc_alloc_history_buffer(scp, imax(*(int *)data, scp->ysize), - TRUE); + scp->ysize, TRUE); + DPRINTF(5, ("error:%d, rows:%d, pool:%d\n", error, + sc_vtb_rows(scp->history), extra_history_size)); + return error; } return ENOIOCTL; diff --git a/sys/dev/syscons/scvidctl.c b/sys/dev/syscons/scvidctl.c index f84b14d..3951425 100644 --- a/sys/dev/syscons/scvidctl.c +++ b/sys/dev/syscons/scvidctl.c @@ -23,7 +23,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: $ + * $Id: scvidctl.c,v 1.9 1999/06/22 14:13:29 yokota Exp $ */ #include "sc.h" @@ -132,6 +132,7 @@ sc_set_text_mode(scr_stat *scp, struct tty *tp, int mode, int xsize, int ysize, video_info_t info; sc_rndr_sw_t *rndr; u_char *font; + int prev_ysize; int error; int s; @@ -188,6 +189,7 @@ sc_set_text_mode(scr_stat *scp, struct tty *tp, int mode, int xsize, int ysize, } /* set up scp */ + prev_ysize = scp->ysize; /* * This is a kludge to fend off scrn_update() while we * muck around with scp. XXX @@ -210,7 +212,7 @@ sc_set_text_mode(scr_stat *scp, struct tty *tp, int mode, int xsize, int ysize, sc_alloc_cut_buffer(scp, FALSE); #endif #ifndef SC_NO_HISTORY - sc_alloc_history_buffer(scp, 0, FALSE); + sc_alloc_history_buffer(scp, 0, prev_ysize, FALSE); #endif scp->rndr = rndr; splx(s); @@ -221,6 +223,8 @@ sc_set_text_mode(scr_stat *scp, struct tty *tp, int mode, int xsize, int ysize, if (tp == NULL) return 0; + DPRINTF(5, ("ws_*size (%d,%d), size (%d,%d)\n", + tp->t_winsize.ws_col, tp->t_winsize.ws_row, scp->xsize, scp->ysize)); if (tp->t_winsize.ws_col != scp->xsize || tp->t_winsize.ws_row != scp->ysize) { tp->t_winsize.ws_col = scp->xsize; @@ -239,6 +243,7 @@ sc_set_graphics_mode(scr_stat *scp, struct tty *tp, int mode) #else video_info_t info; sc_rndr_sw_t *rndr; + int prev_ysize; int error; int s; @@ -259,6 +264,7 @@ sc_set_graphics_mode(scr_stat *scp, struct tty *tp, int mode) } /* set up scp */ + prev_ysize = scp->ysize; scp->status |= (UNKNOWN_MODE | GRAPHICS_MODE); scp->status &= ~PIXEL_MODE; scp->mode = mode; @@ -274,6 +280,9 @@ sc_set_graphics_mode(scr_stat *scp, struct tty *tp, int mode) /* move the mouse cursor at the center of the screen */ sc_mouse_move(scp, scp->xpixel / 2, scp->ypixel / 2); #endif +#ifndef SC_NO_HISTORY + sc_free_history_buffer(scp, prev_ysize); +#endif scp->rndr = rndr; splx(s); @@ -305,6 +314,7 @@ sc_set_pixel_mode(scr_stat *scp, struct tty *tp, int xsize, int ysize, video_info_t info; sc_rndr_sw_t *rndr; u_char *font; + int prev_ysize; int error; int s; @@ -394,6 +404,7 @@ sc_set_pixel_mode(scr_stat *scp, struct tty *tp, int xsize, int ysize, } /* set up scp */ + prev_ysize = scp->ysize; scp->status |= (UNKNOWN_MODE | PIXEL_MODE); scp->status &= ~GRAPHICS_MODE; scp->xsize = xsize; @@ -409,7 +420,7 @@ sc_set_pixel_mode(scr_stat *scp, struct tty *tp, int xsize, int ysize, sc_alloc_cut_buffer(scp, FALSE); #endif #ifndef SC_NO_HISTORY - sc_alloc_history_buffer(scp, 0, FALSE); + sc_alloc_history_buffer(scp, 0, prev_ysize, FALSE); #endif scp->rndr = rndr; splx(s); diff --git a/sys/dev/syscons/syscons.c b/sys/dev/syscons/syscons.c index 4859076..0d45a51 100644 --- a/sys/dev/syscons/syscons.c +++ b/sys/dev/syscons/syscons.c @@ -25,7 +25,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: syscons.c,v 1.311 1999/07/01 20:29:25 peter Exp $ + * $Id: syscons.c,v 1.312 1999/07/01 20:43:03 peter Exp $ */ #include "sc.h" @@ -420,7 +420,7 @@ scmeminit(void *arg) #ifndef SC_NO_HISTORY /* initialize history buffer & pointers */ - sc_alloc_history_buffer(sc_console, 0, FALSE); + sc_alloc_history_buffer(sc_console, 0, 0, FALSE); #endif } @@ -582,11 +582,7 @@ scclose(dev_t dev, int flag, int mode, struct proc *p) else { sc_vtb_destroy(&scp->vtb); sc_vtb_destroy(&scp->scr); - if (scp->history != NULL) { - /* XXX not quite correct */ - sc_vtb_destroy(scp->history); - free(scp->history, M_DEVBUF); - } + sc_free_history_buffer(scp, scp->ysize); free(scp, M_DEVBUF); sc->console[SC_VTY(dev) - sc->first_vty] = NULL; } @@ -3495,7 +3491,7 @@ static scr_stat #endif #ifndef SC_NO_HISTORY - sc_alloc_history_buffer(scp, 0, TRUE); + sc_alloc_history_buffer(scp, 0, 0, TRUE); #endif sc_clear_screen(scp); diff --git a/sys/dev/syscons/syscons.h b/sys/dev/syscons/syscons.h index d7f3d19..d72c622 100644 --- a/sys/dev/syscons/syscons.h +++ b/sys/dev/syscons/syscons.h @@ -25,7 +25,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: syscons.h,v 1.48 1999/06/22 14:13:32 yokota Exp $ + * $Id: syscons.h,v 1.49 1999/06/24 13:04:33 yokota Exp $ */ #ifndef _DEV_SYSCONS_SYSCONS_H_ @@ -430,7 +430,9 @@ void sc_paste(scr_stat *scp, u_char *p, int count); /* schistory.c */ #ifndef SC_NO_HISTORY -int sc_alloc_history_buffer(scr_stat *scp, int lines, int wait); +int sc_alloc_history_buffer(scr_stat *scp, int lines, + int prev_ysize, int wait); +void sc_free_history_buffer(scr_stat *scp, int prev_ysize); void sc_hist_save(scr_stat *scp); #define sc_hist_save_one_line(scp, from) \ sc_vtb_append(&(scp)->vtb, (from), (scp)->history, (scp)->xsize) |