public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Joe Peterson <joe@skyrush.com>
To: Alan Cox <alan@lxorguk.ukuu.org.uk>
Cc: Andrew Morton <akpm@linux-foundation.org>,
	Linux Kernel <linux-kernel@vger.kernel.org>,
	hpa@zytor.com
Subject: Re: [PATCH] Fix backspace on wrapped lines in console (virtual terminal)
Date: Sun, 21 Sep 2008 10:14:22 -0600	[thread overview]
Message-ID: <48D672DE.3010509@skyrush.com> (raw)
In-Reply-To: <48D58C6B.9000403@skyrush.com>

[-- Attachment #1: Type: text/plain, Size: 830 bytes --]

Joe Peterson wrote:
> xterm has a "private mode 45", which turns on reverseWrap, allowing
> backspace to wrap.  This is similar to mode 7 (supported on xterm and
> vt), which is DEVAWM (auto wrap mode).
> 
> I agree that hard-coding backspace/reverse wrap would likely be wrong
> (even though it looks like some terminal emulators I've seen, like
> "screen" add the feature), but would it be appropriate to add mode 45 to
> vt, allowing reverse wrap as an option?

I have worked up a new patch (attached) for review.  It adds the private
mode 45 I mentioned above, but defaults it to off, preserving the old
default of no backspace wrap to the previous line.  This matches xterm's
reverse-wrap behavior (and default settings), so the same escape
sequence can be used to control this mode in both xterm and console/vt.

						-Joe

[-- Attachment #2: vt-fix-wrapped-backspace.patch --]
[-- Type: text/plain, Size: 4289 bytes --]

Fix backspace in the virtual terminal when line is wrapped:

1) Add option for backspace to work when wrapped to next line by adding
   a new private mode 45 to enable reverse wrap (default: off).
   This matches xterm's behavior, which already supports private
   mode 45.

2) Correct the backspace behavior when the most recently typed
   character is in the rightmost column (i.e. in need_wrap state).
   Use high bit of need_wrap (now 2 bits) allow this backspace logic
   to work even when autowrap is off.

Signed-off-by: Joe Peterson <joe@skyrush.com>
---

diff -Nurp a/drivers/char/vt.c b/drivers/char/vt.c
--- a/drivers/char/vt.c	2008-09-21 09:27:43.186681676 -0600
+++ b/drivers/char/vt.c	2008-09-21 09:15:30.826683557 -0600
@@ -1130,12 +1130,36 @@ static inline void cr(struct vc_data *vc
 
 static inline void bs(struct vc_data *vc)
 {
-	if (vc->vc_x) {
-		vc->vc_pos -= 2;
-		vc->vc_x--;
+	if (vc->vc_need_wrap) {
+		/*
+		 * If in need_wrap state (regardless of autowrap mode),
+		 * do not move cursor, but unset need_wrap.
+		 */
 		vc->vc_need_wrap = 0;
-		notify_write(vc, '\b');
+	} else {
+		if (vc->vc_x == 0) {
+			/*
+			 * If at leftmost column, move cursor to end
+			 * of previous line (only if reverse wrap is on).
+			 */
+			if (vc->vc_reverse_wrap) {
+				vc->vc_x = vc->vc_cols - 1;
+				if (vc->vc_y == vc->vc_top) {
+					scrdown(vc,
+						vc->vc_top, vc->vc_bottom, 1);
+					vc->vc_pos += vc->vc_size_row - 2;
+				} else if (vc->vc_y > 0) {
+					vc->vc_y--;
+					vc->vc_pos -= 2;
+				}
+			}
+		} else {
+			/* Normal case: just move cursor back */
+			vc->vc_x--;
+			vc->vc_pos -= 2;
+		}
 	}
+	notify_write(vc, '\b');
 }
 
 static inline void del(struct vc_data *vc)
@@ -1437,6 +1461,9 @@ static void set_mode(struct vc_data *vc,
 			case 25:		/* Cursor on/off */
 				vc->vc_deccm = on_off;
 				break;
+			case 45:		/* Reverse wrap on/off */
+				vc->vc_reverse_wrap = on_off;
+				break;
 			case 1000:
 				vc->vc_report_mouse = on_off ? 2 : 0;
 				break;
@@ -1621,6 +1648,7 @@ static void reset_terminal(struct vc_dat
 	vc->vc_decscnm		= 0;
 	vc->vc_decom		= 0;
 	vc->vc_decawm		= 1;
+	vc->vc_reverse_wrap	= 0;
 	vc->vc_deccm		= 1;
 	vc->vc_decim		= 0;
 
@@ -2320,9 +2348,9 @@ rescan_last_byte:
 			}
 
 			while (1) {
-				if (vc->vc_need_wrap || vc->vc_decim)
+				if ((vc->vc_need_wrap & 1) || vc->vc_decim)
 					FLUSH
-				if (vc->vc_need_wrap) {
+				if (vc->vc_need_wrap & 1) {
 					cr(vc);
 					lf(vc);
 				}
@@ -2337,7 +2365,12 @@ rescan_last_byte:
 					draw_from = vc->vc_pos;
 				}
 				if (vc->vc_x == vc->vc_cols - 1) {
-					vc->vc_need_wrap = vc->vc_decawm;
+					/*
+					 * Set high bit of need_wrap regardless
+					 * of autowrap mode (backspace logic
+					 * relies on this).
+					 */
+					vc->vc_need_wrap = 2 | vc->vc_decawm;
 					draw_to = vc->vc_pos + 2;
 				} else {
 					vc->vc_x++;
@@ -2496,12 +2529,12 @@ static void vt_console_print(struct cons
 	 * Problems caused when we have need_wrap set on '\n' character */
 	while (count--) {
 		c = *b++;
-		if (c == 10 || c == 13 || c == 8 || vc->vc_need_wrap) {
+		if (c == 10 || c == 13 || c == 8 || (vc->vc_need_wrap & 1)) {
 			if (cnt > 0) {
 				if (CON_IS_VISIBLE(vc))
 					vc->vc_sw->con_putcs(vc, start, cnt, vc->vc_y, vc->vc_x);
 				vc->vc_x += cnt;
-				if (vc->vc_need_wrap)
+				if (vc->vc_need_wrap & 1)
 					vc->vc_x--;
 				cnt = 0;
 			}
diff -Nurp a/include/linux/console_struct.h b/include/linux/console_struct.h
--- a/include/linux/console_struct.h	2008-09-21 09:15:16.136681289 -0600
+++ b/include/linux/console_struct.h	2008-09-21 09:15:30.956686803 -0600
@@ -71,6 +71,7 @@ struct vc_data {
 	unsigned int	vc_decscnm	: 1;	/* Screen Mode */
 	unsigned int	vc_decom	: 1;	/* Origin Mode */
 	unsigned int	vc_decawm	: 1;	/* Autowrap Mode */
+	unsigned int	vc_reverse_wrap	: 1;	/* Reverse wrap Mode */
 	unsigned int	vc_deccm	: 1;	/* Cursor Visible */
 	unsigned int	vc_decim	: 1;	/* Insert Mode */
 	unsigned int	vc_deccolm	: 1;	/* 80/132 Column Mode */
@@ -87,7 +88,7 @@ struct vc_data {
 	unsigned int	vc_s_reverse	: 1;
 	/* misc */
 	unsigned int	vc_ques		: 1;
-	unsigned int	vc_need_wrap	: 1;
+	unsigned int	vc_need_wrap	: 2;
 	unsigned int	vc_can_do_color	: 1;
 	unsigned int	vc_report_mouse : 2;
 	unsigned int	vc_kmalloced	: 1;

  reply	other threads:[~2008-09-21 16:14 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-09-20 16:25 [PATCH] Fix backspace on wrapped lines in console (virtual terminal) Joe Peterson
2008-09-20 16:38 ` Alan Cox
2008-09-20 16:48   ` Joe Peterson
2008-09-20 23:51   ` Joe Peterson
2008-09-21 16:14     ` Joe Peterson [this message]
2008-09-23 20:39       ` Joe Peterson

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=48D672DE.3010509@skyrush.com \
    --to=joe@skyrush.com \
    --cc=akpm@linux-foundation.org \
    --cc=alan@lxorguk.ukuu.org.uk \
    --cc=hpa@zytor.com \
    --cc=linux-kernel@vger.kernel.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