From mark@globalnet.co.uk Wed Sep 15 10:54:32 1999
Return-Path: <mark@globalnet.co.uk>
Received: from sand5.global.net.uk (sand5.mail.gxn.net [194.126.80.249])
	by hub.freebsd.org (Postfix) with ESMTP id 5998915245
	for <FreeBSD-gnats-submit@freebsd.org>; Wed, 15 Sep 1999 10:54:05 -0700 (PDT)
	(envelope-from mark@globalnet.co.uk)
Received: from p25s13a07.client.global.net.uk ([195.147.237.38] helo=marder-1.)
	by sand5.global.net.uk with esmtp (Exim 2.05 #1)
	id 11RJFq-0005uT-00
	for FreeBSD-gnats-submit@freebsd.org; Wed, 15 Sep 1999 18:54:03 +0100
Received: (from root@localhost)
	by marder-1. (8.9.2/8.8.8) id SAA06547;
	Wed, 15 Sep 1999 18:45:37 +0100 (BST)
	(envelope-from mark)
Message-Id: <199909151745.SAA06547@marder-1.>
Date: Wed, 15 Sep 1999 18:45:37 +0100 (BST)
From: Mark Ovens <mark@ukug.uk.freebsd.org>
Sender: mark@globalnet.co.uk
Reply-To: Mark Ovens <mark@ukug.uk.freebsd.org>
To: FreeBSD-gnats-submit@freebsd.org
Subject: [PATCH] Stop syscons from flushing history buffer when changing video mode
X-Send-Pr-Version: 3.2

>Number:         13764
>Category:       kern
>Synopsis:       [PATCH] Stop syscons from flushing history buffer when changing video mode
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    yokota
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Wed Sep 15 11:00:01 PDT 1999
>Closed-Date:    Fri Jun 22 08:43:55 PDT 2001
>Last-Modified:  Fri Jun 22 08:44:01 PDT 2001
>Originator:     Mark Ovens
>Release:        FreeBSD 3.1-RELEASE i386
>Organization:
>Environment:

	FreeBSD marder-1 3.1-RELEASE FreeBSD 3.1-RELEASE #33:
	Wed Sep 15 18:12:58 BST 1999
	mark@marder-1:/usr/src/sys/compile/MARDER-1  i386

>Description:

	When the console video mode is changed, with vidcontrol,
	syscons free()s the current history buffer and malloc()s
	a new one which means that the scroll-back buffer is lost.

	This can be a problem if the video mode is set in /etc/rc.conf
	(e.g. ``allscreens_flags="80x43"'') and a process which is started
	from an rc* file fails to start as you cannot scroll back to look
	at the error messages.

>How-To-Repeat:

	Add ``allscreens_flags="80x43"'' to /etc/rc.conf, reboot, hit
	the Scroll Lock key, then PgUp.

>Fix:
	

*** /usr/src/sys/dev/syscons/syscons.c.orig	Wed Sep  8 18:42:25 1999
--- /usr/src/sys/dev/syscons/syscons.c	Wed Sep 15 18:13:19 1999
***************
*** 3320,3347 ****
  void
  sc_alloc_history_buffer(scr_stat *scp, int lines, int extra, int wait)
  {
!     u_short *usp;
  
!     if (lines < scp->ysize)
! 	lines = scp->ysize;
  
!     usp = scp->history;
!     scp->history = NULL;
!     if (usp != NULL) {
! 	free(usp, M_DEVBUF);
! 	if (extra > 0)
  	    extra_history_size += extra;
      }
  
      scp->history_size = lines * scp->xsize;
      if (lines > imax(sc_history_size, scp->ysize))
  	extra_history_size -= lines - imax(sc_history_size, scp->ysize);
!     usp = (u_short *)malloc(scp->history_size * sizeof(u_short), 
  			    M_DEVBUF, (wait) ? M_WAITOK : M_NOWAIT);
!     if (usp != NULL)
! 	bzero(usp, scp->history_size * sizeof(u_short));
!     scp->history_head = scp->history_pos = usp;
!     scp->history = usp;
  }
  
  static scr_stat
--- 3320,3380 ----
  void
  sc_alloc_history_buffer(scr_stat *scp, int lines, int extra, int wait)
  {
!     u_short *new, *old;
!     u_short head_offset = 0, pos_offset = 0;
!     int i, j;
!     int old_size = 0;
  
!     old = NULL;
! 
!     if (scp->history != NULL) {
! 
! 	/* Save pointer offsets and size of the old buffer */
  
!     	head_offset = scp->history_head - scp->history;
!     	pos_offset = scp->history_pos - scp->history;
!     	old_size = scp->history_size;
!     	if (extra > 0)
  	    extra_history_size += extra;
      }
  
+     if (lines < scp->ysize)
+ 	lines = scp->ysize;
+ 
      scp->history_size = lines * scp->xsize;
      if (lines > imax(sc_history_size, scp->ysize))
  	extra_history_size -= lines - imax(sc_history_size, scp->ysize);
!     new = (u_short *)malloc(scp->history_size * sizeof(u_short), 
  			    M_DEVBUF, (wait) ? M_WAITOK : M_NOWAIT);
!     if (new != NULL)
! 	bzero(new, scp->history_size * sizeof(u_short));
! 
!     /* Copy contents of old buffer to the new one, but start at
!      * the end and work back. This ensures that if the new buffer
!      * is smaller than the old one then the oldest data is
!      * truncated rather than the latest.
!      */
! 
!     if (scp->history != NULL) {
! 	    i = scp->history_size - 1;
! 	    j = old_size - 1;
! 
! 	    while (i >= 0 && j >= 0)
! 		    *(new + i--) = *(scp->history + j--);
! 
! 	    old = scp->history;
! 	    scp->history = new;
! 
! 	    scp->history_head = scp->history_pos = scp->history + head_offset;
! 	    scp->history_pos = scp->history_pos = scp->history + pos_offset;
! 
!     } else
! 	    scp->history = scp->history_head = scp->history_pos = new;
! 
!     if (old != NULL) {
! 	free(old, M_DEVBUF);
! 
!     }
  }
  
  static scr_stat
*** /usr/src/sys/dev/syscons/scvidctl.c.orig	Tue Sep  7 20:53:19 1999
--- /usr/src/sys/dev/syscons/scvidctl.c	Wed Sep 15 00:44:55 1999
***************
*** 86,91 ****
--- 86,107 ----
      int s;
      int i;
  
+     /* Copy screen into the top of the history buffer. This must
+      * be done here so that scp->{x,y}size are still set to the
+      * old mode values. Any later and we will copy too few or too
+      * many (the extra will be garbage) lines.
+      */
+ 
+     for (i = 0; i < scp->ysize; i++) {
+ 	bcopy(scp->scr_buf + (scp->xsize * i), scp->history_head,
+ 			scp->xsize * sizeof(u_short));
+ 
+ 	scp->history_head += scp->xsize;
+ 
+ 	if (scp->history_head + scp->xsize > scp->history + scp->history_size)
+ 	    scp->history_head=scp->history;
+     }
+ 
      if ((*vidsw[scp->ad]->get_info)(scp->adp, mode, &info))
  	return ENODEV;
   
***************
*** 138,153 ****
      scp->xpixel = scp->xsize*8;
      scp->ypixel = scp->ysize*fontsize;
  
      /* allocate buffers */
      sc_alloc_scr_buffer(scp, TRUE, TRUE);
      if (ISMOUSEAVAIL(scp->adp->va_flags))
  	sc_alloc_cut_buffer(scp, FALSE);
      sc_alloc_history_buffer(scp, sc_history_size, i, FALSE);
      splx(s);
- 
-     if (scp == cur_console)
- 	set_mode(scp);
-     scp->status &= ~UNKNOWN_MODE;
  
      if (tp == NULL)
  	return 0;
--- 154,173 ----
      scp->xpixel = scp->xsize*8;
      scp->ypixel = scp->ysize*fontsize;
  
+     /* We need to call set_mode() before sc_alloc_history_buffer()
+      * or the history buffer will get screwed up.
+      */
+ 
+     if (scp == cur_console)
+ 	set_mode(scp);
+     scp->status &= ~UNKNOWN_MODE;
+ 
      /* allocate buffers */
      sc_alloc_scr_buffer(scp, TRUE, TRUE);
      if (ISMOUSEAVAIL(scp->adp->va_flags))
  	sc_alloc_cut_buffer(scp, FALSE);
      sc_alloc_history_buffer(scp, sc_history_size, i, FALSE);
      splx(s);
  
      if (tp == NULL)
  	return 0;


>Release-Note:
>Audit-Trail:

From: Kazutaka YOKOTA <yokota@zodiac.mech.utsunomiya-u.ac.jp>
To: Mark Ovens <mark@ukug.uk.freebsd.org>
Cc: FreeBSD-gnats-submit@freebsd.org,
	yokota@zodiac.mech.utsunomiya-u.ac.jp
Subject: Re: kern/13764: [PATCH] Stop syscons from flushing history buffer when
	 changing video mode 
Date: Thu, 16 Sep 1999 10:48:10 +0900

 >>Number:         13764
 >>Category:       kern
 >>Synopsis:       [PATCH] Stop syscons from flushing history buffer when changi
 >ng video mode
 [...]
 >>Arrival-Date:   Wed Sep 15 11:00:01 PDT 1999
 >>Closed-Date:
 >>Last-Modified:
 >>Originator:     Mark Ovens
 >>Release:        FreeBSD 3.1-RELEASE i386
 >>Organization:
 >>Environment:
 >
 >	FreeBSD marder-1 3.1-RELEASE FreeBSD 3.1-RELEASE #33:
 >	Wed Sep 15 18:12:58 BST 1999
 >	mark@marder-1:/usr/src/sys/compile/MARDER-1  i386
 >
 >>Description:
 >
 >	When the console video mode is changed, with vidcontrol,
 >	syscons free()s the current history buffer and malloc()s
 >	a new one which means that the scroll-back buffer is lost.
 >
 >	This can be a problem if the video mode is set in /etc/rc.conf
 >	(e.g. ``allscreens_flags="80x43"'') and a process which is started
 >	from an rc* file fails to start as you cannot scroll back to look
 >	at the error messages.
 
 This has been brought up several times before.  I will work on
 this.  Thank you.
 
 Kazu
 
 
Responsible-Changed-From-To: freebsd-bugs->yokota 
Responsible-Changed-By: sheldonh 
Responsible-Changed-When: Thu Sep 16 01:13:23 PDT 1999 
Responsible-Changed-Why:  
Over to Mr Syscons. 

From: Mark Ovens <mark@ukug.uk.freebsd.org>
To: FreeBSD-gnats-submit@freebsd.org
Cc:  
Subject: Re: kern/13764: [PATCH] Stop syscons from flushing history buffer when changing video mode
Date: Fri, 17 Sep 1999 18:15:30 +0100 (BST)

 >Submitter-Id:   current-users
 >Originator:     Mark Ovens
 >Organization:   
 >Confidential:   no
 >Synopsis:       [PATCH] Stop syscons from flushing history buffer when changing video mode
 >Severity:       non-critical
 >Priority:       low
 >Category:       kern
 >Release:        FreeBSD 3.1-RELEASE i386
 >Class:          change-request
 >Environment: 
 
 	
 
 >Description: 
 
 	I just discovered a couple of careless yank and pastes in my code.
 	It doesn't affect the logic, just redundant assignments.
 
 	New diff below:
 
 >How-To-Repeat: 
 
 	
 
 >Fix: 
 	
 
 *** syscons.c.orig	Wed Sep  8 18:42:25 1999
 --- syscons.c	Fri Sep 17 17:33:53 1999
 ***************
 *** 3320,3347 ****
   void
   sc_alloc_history_buffer(scr_stat *scp, int lines, int extra, int wait)
   {
 !     u_short *usp;
   
 !     if (lines < scp->ysize)
 ! 	lines = scp->ysize;
   
 !     usp = scp->history;
 !     scp->history = NULL;
 !     if (usp != NULL) {
 ! 	free(usp, M_DEVBUF);
 ! 	if (extra > 0)
   	    extra_history_size += extra;
       }
   
       scp->history_size = lines * scp->xsize;
       if (lines > imax(sc_history_size, scp->ysize))
   	extra_history_size -= lines - imax(sc_history_size, scp->ysize);
 !     usp = (u_short *)malloc(scp->history_size * sizeof(u_short), 
   			    M_DEVBUF, (wait) ? M_WAITOK : M_NOWAIT);
 !     if (usp != NULL)
 ! 	bzero(usp, scp->history_size * sizeof(u_short));
 !     scp->history_head = scp->history_pos = usp;
 !     scp->history = usp;
   }
   
   static scr_stat
 --- 3320,3380 ----
   void
   sc_alloc_history_buffer(scr_stat *scp, int lines, int extra, int wait)
   {
 !     u_short *new, *old;
 !     u_short head_offset = 0, pos_offset = 0;
 !     int i, j;
 !     int old_size = 0;
   
 !     old = NULL;
 ! 
 !     if (scp->history != NULL) {
 ! 
 ! 	/* Save pointer offsets and size of the old buffer */
   
 !     	head_offset = scp->history_head - scp->history;
 !     	pos_offset = scp->history_pos - scp->history;
 !     	old_size = scp->history_size;
 !     	if (extra > 0)
   	    extra_history_size += extra;
       }
   
 +     if (lines < scp->ysize)
 + 	lines = scp->ysize;
 + 
       scp->history_size = lines * scp->xsize;
       if (lines > imax(sc_history_size, scp->ysize))
   	extra_history_size -= lines - imax(sc_history_size, scp->ysize);
 !     new = (u_short *)malloc(scp->history_size * sizeof(u_short), 
   			    M_DEVBUF, (wait) ? M_WAITOK : M_NOWAIT);
 !     if (new != NULL)
 ! 	bzero(new, scp->history_size * sizeof(u_short));
 ! 
 !     /* Copy contents of old buffer to the new one, but start at
 !      * the end and work back. This ensures that if the new buffer
 !      * is smaller than the old one then the oldest data is
 !      * truncated rather than the latest.
 !      */
 ! 
 !     if (scp->history != NULL) {
 ! 	    i = scp->history_size - 1;
 ! 	    j = old_size - 1;
 ! 
 ! 	    while (i >= 0 && j >= 0)
 ! 		    *(new + i--) = *(scp->history + j--);
 ! 
 ! 	    old = scp->history;
 ! 	    scp->history = new;
 ! 
 ! 	    scp->history_head = scp->history + head_offset;
 ! 	    scp->history_pos = scp->history + pos_offset;
 ! 
 !     } else
 ! 	    scp->history = scp->history_head = scp->history_pos = new;
 ! 
 !     if (old != NULL) {
 ! 	free(old, M_DEVBUF);
 ! 
 !     }
   }
   
   static scr_stat
 *** scvidctl.c.orig	Tue Sep  7 20:53:19 1999
 --- scvidctl.c	Wed Sep 15 00:44:55 1999
 ***************
 *** 86,91 ****
 --- 86,107 ----
       int s;
       int i;
   
 +     /* Copy screen into the top of the history buffer. This must
 +      * be done here so that scp->{x,y}size are still set to the
 +      * old mode values. Any later and we will copy too few or too
 +      * many (the extra will be garbage) lines.
 +      */
 + 
 +     for (i = 0; i < scp->ysize; i++) {
 + 	bcopy(scp->scr_buf + (scp->xsize * i), scp->history_head,
 + 			scp->xsize * sizeof(u_short));
 + 
 + 	scp->history_head += scp->xsize;
 + 
 + 	if (scp->history_head + scp->xsize > scp->history + scp->history_size)
 + 	    scp->history_head=scp->history;
 +     }
 + 
       if ((*vidsw[scp->ad]->get_info)(scp->adp, mode, &info))
   	return ENODEV;
    
 ***************
 *** 138,153 ****
       scp->xpixel = scp->xsize*8;
       scp->ypixel = scp->ysize*fontsize;
   
       /* allocate buffers */
       sc_alloc_scr_buffer(scp, TRUE, TRUE);
       if (ISMOUSEAVAIL(scp->adp->va_flags))
   	sc_alloc_cut_buffer(scp, FALSE);
       sc_alloc_history_buffer(scp, sc_history_size, i, FALSE);
       splx(s);
 - 
 -     if (scp == cur_console)
 - 	set_mode(scp);
 -     scp->status &= ~UNKNOWN_MODE;
   
       if (tp == NULL)
   	return 0;
 --- 154,173 ----
       scp->xpixel = scp->xsize*8;
       scp->ypixel = scp->ysize*fontsize;
   
 +     /* We need to call set_mode() before sc_alloc_history_buffer()
 +      * or the history buffer will get screwed up.
 +      */
 + 
 +     if (scp == cur_console)
 + 	set_mode(scp);
 +     scp->status &= ~UNKNOWN_MODE;
 + 
       /* allocate buffers */
       sc_alloc_scr_buffer(scp, TRUE, TRUE);
       if (ISMOUSEAVAIL(scp->adp->va_flags))
   	sc_alloc_cut_buffer(scp, FALSE);
       sc_alloc_history_buffer(scp, sc_history_size, i, FALSE);
       splx(s);
   
       if (tp == NULL)
   	return 0;
 

From: parish <stonewall@btinternet.com>
To: freebsd-gnats-submit@FreeBSD.org
Cc:  
Subject: Re: kern/13764: [PATCH] Stop syscons from flushing history buffer when 
 changing video mode
Date: Tue, 23 May 2000 22:24:17 +0100

 I reckon that this PR can be closed now. syscons(4) has had a major
 re-write in 4.0 and this functionality is now included.
 
State-Changed-From-To: open->closed 
State-Changed-By: phk 
State-Changed-When: Fri Jun 22 08:43:55 PDT 2001 
State-Changed-Why:  
done 

http://www.FreeBSD.org/cgi/query-pr.cgi?pr=13764 
>Unformatted:
