public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Jamie Lokier <lk@tantalophile.demon.co.uk>
To: Pavel Machek <pavel@suse.cz>
Cc: Simon Hay <simon@haywired.org>, linux-kernel@vger.kernel.org
Subject: Re: Multiple monitors
Date: Thu, 13 Sep 2001 13:51:40 +0100	[thread overview]
Message-ID: <20010913135140.A1397@kushida.degree2.com> (raw)
In-Reply-To: <20010903214829.B17488@unthought.net> <Pine.LNX.4.33.0109032107280.2297-100000@localhost.localdomain> <20010907015556.A7329@kushida.degree2.com> <20010911005848.A1005@bug.ucw.cz>
In-Reply-To: <20010911005848.A1005@bug.ucw.cz>; from pavel@suse.cz on Tue, Sep 11, 2001 at 12:58:48AM +0200

Pavel Machek wrote:
> > On one 686 class machine, I saw text mode take nearly two seconds to
> > scroll the screen, when all but one line of the screen was being
> > scrolled (so it had to copy everything).  This was in pure text mode,
> > not even a framebuffer!  In X it was invisibly fast.
> 
> 2 seconds on vga console is way too much. It could happen with
> framebuffer + usb hogging PCI...

No, this was in 1996 on a Pentium Pro machine, with no USB or x86
framebuffer drivers even written then :-)  It was plain 80x50 text mode,
really.

I still have the patch I wrote in March 1997 (attached for reference),
and this patch made a _huge_ difference to text mode Emacs on those
machines.  An equivalent fix seems to have been incorporated in
console.c by now.

enjoy,
-- Jamie

--- linux/drivers/char/console.c.dist	Tue Jan 14 22:01:17 1997
+++ linux/drivers/char/console.c	Tue Feb 25 03:40:26 1997
@@ -592,15 +592,22 @@
 	__set_origin(__real_origin);
 }
 
-void scrup(int currcons, unsigned int t, unsigned int b)
+static void scrup(int currcons, unsigned int t, unsigned int b, unsigned int nr)
 {
 	int hardscroll = hardscroll_enabled;
 
-	if (b > video_num_lines || t >= b)
+	if (b > video_num_lines || t >= b || nr == 0)
 		return;
+	if (nr > b - t)
+		nr = b - t;
 	if (t || b != video_num_lines)
 		hardscroll = 0;
 	if (hardscroll) {
+		if (nr != 1) {
+			while (nr--)
+				scrup (currcons, t, b, 1);
+			return;
+		}
 		origin += video_size_row;
 		pos += video_size_row;
 		scr_end += video_size_row;
@@ -639,14 +646,14 @@
 		set_origin(currcons);
 	} else {
 		unsigned short * d = (unsigned short *) (origin+video_size_row*t);
-		unsigned short * s = (unsigned short *) (origin+video_size_row*(t+1));
-		unsigned int count = (b-t-1) * video_num_columns;
+		unsigned short * s = (unsigned short *) (origin+video_size_row*(t+nr));
+		unsigned int count = (b-t-nr) * video_num_columns;
 
 		while (count) {
 			count--;
 			scr_writew(scr_readw(s++), d++);
 		}
-		count = video_num_columns;
+		count = nr*video_num_columns;
 		while (count) {
 			count--;
 			scr_writew(video_erase_char, d++);
@@ -654,27 +661,28 @@
 	}
 }
 
-void
-scrdown(int currcons, unsigned int t, unsigned int b)
+static void
+scrdown(int currcons, unsigned int t, unsigned int b, unsigned int nr)
 {
 	unsigned short *d, *s;
 	unsigned int count;
 
-	if (b > video_num_lines || t >= b)
+	if (b > video_num_lines || t >= b || nr == 0)
 		return;
+	if (nr > b - t)
+		nr = b - t;
 	d = (unsigned short *) (origin+video_size_row*b);
-	s = (unsigned short *) (origin+video_size_row*(b-1));
-	count = (b-t-1)*video_num_columns;
+	s = (unsigned short *) (origin+video_size_row*(b-nr));
+	count = (b-t-nr)*video_num_columns;
 	while (count) {
 		count--;
 		scr_writew(scr_readw(--s), --d);
 	}
-	count = video_num_columns;
+	count = nr*video_num_columns;
 	while (count) {
 		count--;
 		scr_writew(video_erase_char, --d);
 	}
-	has_scrolled = 1;
 }
 
 static void lf(int currcons)
@@ -683,7 +691,7 @@
 	 * if below scrolling region
 	 */
     	if (y+1 == bottom)
-		scrup(currcons,top,bottom);
+		scrup(currcons,top,bottom,1);
 	else if (y < video_num_lines-1) {
 	    	y++;
 		pos += video_size_row;
@@ -697,7 +705,7 @@
 	 * if above scrolling region
 	 */
 	if (y == top)
-		scrdown(currcons,top,bottom);
+		scrdown(currcons,top,bottom,1);
 	else if (y > 0) {
 		y--;
 		pos -= video_size_row;
@@ -1171,84 +1179,61 @@
 	}
 }
 
-static void insert_char(int currcons)
+static void insert_chars(int currcons, unsigned int nr)
 {
-	unsigned int i = x;
-	unsigned short tmp, old = video_erase_char;
+	unsigned int count;
 	unsigned short * p = (unsigned short *) pos;
 
-	while (i++ < video_num_columns) {
-		tmp = scr_readw(p);
-		scr_writew(old, p);
-		old = tmp;
-		p++;
+	if (nr >= video_num_columns - x)
+		nr = video_num_columns - x;
+	if (nr == 0)
+		return;
+
+	p += video_num_columns - x;
+	count = video_num_columns - x - nr;
+	while (count--) {
+		p--;
+		scr_writew(scr_readw(p-nr), p);
 	}
+	count = nr;
+	while (count--)
+		scr_writew(video_erase_char, --p);
+
 	need_wrap = 0;
 }
 
-static void insert_line(int currcons)
+static inline void insert_lines(int currcons, unsigned int nr)
 {
-	scrdown(currcons,y,bottom);
+	scrdown(currcons,y,bottom,nr);
 	need_wrap = 0;
 }
 
-static void delete_char(int currcons)
+static void delete_chars(int currcons, unsigned int nr)
 {
-	unsigned int i = x;
+	unsigned int count;
 	unsigned short * p = (unsigned short *) pos;
 
-	while (++i < video_num_columns) {
-		scr_writew(scr_readw(p+1), p);
+	if (nr >= video_num_columns - x)
+		nr = video_num_columns - x;
+	if (nr == 0)
+		return;
+
+	count = video_num_columns - x - nr;
+	while (count--) {
+		scr_writew(scr_readw(p+nr), p);
 		p++;
 	}
-	scr_writew(video_erase_char, p);
-	need_wrap = 0;
-}
+	count = nr;
+	while (count--)
+		scr_writew(video_erase_char, p++);
 
-static void delete_line(int currcons)
-{
-	scrup(currcons,y,bottom);
 	need_wrap = 0;
 }
 
-static void csi_at(int currcons, unsigned int nr)
-{
-	if (nr > video_num_columns)
-		nr = video_num_columns;
-	else if (!nr)
-		nr = 1;
-	while (nr--)
-		insert_char(currcons);
-}
-
-static void csi_L(int currcons, unsigned int nr)
-{
-	if (nr > video_num_lines)
-		nr = video_num_lines;
-	else if (!nr)
-		nr = 1;
-	while (nr--)
-		insert_line(currcons);
-}
-
-static void csi_P(int currcons, unsigned int nr)
-{
-	if (nr > video_num_columns)
-		nr = video_num_columns;
-	else if (!nr)
-		nr = 1;
-	while (nr--)
-		delete_char(currcons);
-}
-
-static void csi_M(int currcons, unsigned int nr)
+static inline void delete_lines(int currcons, unsigned int nr)
 {
-	if (nr > video_num_lines)
-		nr = video_num_lines;
-	else if (!nr)
-		nr=1;
-	while (nr--)
-		delete_line(currcons);
+	scrup(currcons,y,bottom,nr);
+	need_wrap = 0;
 }
 
 static void save_cur(int currcons)
@@ -1468,7 +1453,7 @@
 				lf(currcons);
 			}
 			if (decim)
-				insert_char(currcons);
+				insert_chars(currcons, 1);
 			scr_writew( video_mode_512ch ?
 			   ((attr & 0xf7) << 8) + ((tc & 0x100) << 3) +
 			   (tc & 0x0ff) : (attr << 8) + tc,
@@ -1707,13 +1692,13 @@
 						csi_K(currcons,par[0]);
 						continue;
 					case 'L':
-						csi_L(currcons,par[0]);
+						insert_lines(currcons,(par[0] ? par[0] : 1));
 						continue;
 					case 'M':
-						csi_M(currcons,par[0]);
+						delete_lines(currcons,(par[0] ? par[0] : 1));
 						continue;
 					case 'P':
-						csi_P(currcons,par[0]);
+						delete_chars(currcons,(par[0] ? par[0] : 1));
 						continue;
 					case 'c':
 						if (!par[0])
@@ -1762,7 +1747,7 @@
 						csi_X(currcons, par[0]);
 						continue;
 					case '@':
-						csi_at(currcons,par[0]);
+						insert_chars(currcons,(par[0] ? par[0] : 1));
 						continue;
 					case ']': /* setterm functions */
 						setterm_command(currcons);
--- linux/drivers/char/vt.c.dist	Wed Feb  5 20:04:38 1997
+++ linux/drivers/char/vt.c	Tue Feb 25 03:42:23 1997
@@ -28,6 +28,7 @@
 #include "vt_kern.h"
 #include "diacr.h"
 #include "selection.h"
+#include "console_struct.h"	/* for `vc_has_scrolled' */
 
 extern char vt_dont_switch;
 extern struct tty_driver console_driver;
@@ -299,9 +300,10 @@
 		/*
 		 * explicitly blank/unblank the screen if switching modes
 		 */
-		if (arg == KD_TEXT)
+		if (arg == KD_TEXT) {
+			vc_cons[console].d->vc_has_scrolled = 1;
 			do_unblank_screen();
-		else
+		} else
 			do_blank_screen(1);
 		return 0;
 

  reply	other threads:[~2001-09-13 12:52 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2001-09-03 18:44 Multiple monitors Simon Hay
2001-09-03 19:48 ` Jakob Østergaard
2001-09-03 20:11   ` Simon Hay
2001-09-03 20:49     ` Wakko Warner
2001-09-03 20:42       ` Simon Hay
2001-09-03 20:52       ` Jan Kasprzak
2001-09-04 16:52       ` James Simmons
2001-09-07  0:55     ` Jamie Lokier
2001-09-10 22:58       ` Pavel Machek
2001-09-13 12:51         ` Jamie Lokier [this message]
2001-09-03 20:57 ` Matan Ziv-Av
2001-09-04  7:56 ` Ghozlane Toumi
2001-09-04 16:44 ` James Simmons
2001-09-05 18:01 ` sacx
2001-09-05 18:13   ` sacx

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20010913135140.A1397@kushida.degree2.com \
    --to=lk@tantalophile.demon.co.uk \
    --cc=linux-kernel@vger.kernel.org \
    --cc=pavel@suse.cz \
    --cc=simon@haywired.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox