summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/dev/syscons/schistory.c82
-rw-r--r--sys/dev/syscons/scvidctl.c17
-rw-r--r--sys/dev/syscons/syscons.c12
-rw-r--r--sys/dev/syscons/syscons.h6
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)
OpenPOWER on IntegriCloud