9front - general discussion about 9front
 help / color / mirror / Atom feed
From: Amavect <amavect@gmail.com>
To: 9front@9front.org
Subject: [9front] [drawterm] [PATCH] fix backspace deleting login prompt
Date: Fri, 12 Apr 2024 23:59:09 -0500	[thread overview]
Message-ID: <CAGOW0YNHHynkjTepTqvvfGfuQTU4ty3nqTyFfjJmcniLCpqRQg@mail.gmail.com> (raw)

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

fix backspace deleting login prompt

devkbd directly echos to the terminal,
but it doesn't know the line buffer length.
Instead, let devcons control the echoing.

Move kbd functions from devcons into devkbd.
Remove kbdputc from fns.h
Create consreadkbdline to reduce indentation.
Remove the now unneeded precondition in the echo function.

Backspace now deletes a UTF-8 codepoint during the login prompt.
Visual mismatch may still happen if a codepoint is not a glyph.
It's good enough for now.

Thanks,
Amavect

[-- Attachment #2.1: Type: text/plain, Size: 455 bytes --]

from postmaster@9front:
The following attachment had content that we can't
prove to be harmless.  To avoid possible automatic
execution, we changed the content headers.
The original header was:

	Content-Type: text/x-patch; charset="US-ASCII"; 
	name="0001-fix-backspace-deleting-login-prompt.patch"
	Content-Disposition: attachment; 
	filename="0001-fix-backspace-deleting-login-prompt.patch"
	Content-Transfer-Encoding: base64
	Content-ID: <f_luxmj1040>

[-- Attachment #2.2: 0001-fix-backspace-deleting-login-prompt.patch.suspect --]
[-- Type: application/octet-stream, Size: 5704 bytes --]

From 7f0f4210b60b912032737146fb036cefd71d670b Mon Sep 17 00:00:00 2001
From: Amavect <amavect@gmail.com>
Date: Fri, 12 Apr 2024 23:38:40 -0500
Subject: [PATCH] fix backspace deleting login prompt

devkbd directly echos to the terminal,
but it doesn't know the line buffer length.
Instead, let devcons control the echoing.

Move kbd functions from devcons into devkbd.
Remove kbdputc from fns.h
Create consreadkbdline to reduce indentation.
Remove the now unneeded precondition in the echo function.

Backspace now deletes a UTF-8 codepoint during the login prompt.
Visual mismatch may still happen if a codepoint is not a glyph.
It's good enough for now.
---
 kern/devcons.c | 139 ++++++++++++++++++-------------------------------
 kern/devkbd.c  |  58 ++++++++++++++++++++-
 kern/fns.h     |   1 -
 3 files changed, 108 insertions(+), 90 deletions(-)

diff --git a/kern/devcons.c b/kern/devcons.c
index 8c94993..aa4438d 100644
--- a/kern/devcons.c
+++ b/kern/devcons.c
@@ -4,8 +4,6 @@
 #include	"fns.h"
 #include	"error.h"
 
-#include 	"keyboard.h"
-
 #include	<authsrv.h>
 
 #undef write
@@ -267,68 +265,16 @@ echoscreen(char *buf, int n)
 static void
 echo(char *buf, int n)
 {
-	if(kbd.raw)
-		return;
 	if(screenputs != 0)
 		echoscreen(buf, n);
 	else
 		write(1, buf, n);
 }
 
-static int
-_kbdputc(Queue *q, int c)
-{
-	char buf[UTFmax];
-	Rune r = c;
-	int n;
-
-	if((n = runetochar(buf, &r)) > 0){
-		echo(buf, n);
-		qproduce(q, buf, n);
-	}
-	return 0;
-}
-
-/* _kbdputc, but with compose translation */
-int
-kbdputc(Queue *q, int c)
+static void
+echochar(char c)
 {
-	static int collecting, nk;
-	static Rune kc[5];
-	int i;
-
-	switch(c){
-	case 0:
-	case Kcaps:
-	case Knum:
-	case Kshift:
-	case Kaltgr:
-	case Kmod4:
-	case Kctl:
-		/* ignore modifiers; see nextrune() of kbdfs */
-		return 0;
-
-	case Kalt:
-		collecting = 1;
-		nk = 0;
-		return 0;
-	}
-
-	if(!collecting)
-		return _kbdputc(q, c);
-
-	kc[nk++] = c;
-	c = latin1(kc, nk);
-	if(c < -1)  /* need more keystrokes */
-		return 0;
-	if(c != -1) /* valid sequence */
-		_kbdputc(q, c);
-	else
-		for(i=0; i<nk; i++)
-			_kbdputc(q, kc[i]);
-	nk = 0;
-	collecting = 0;
-	return 0;
+	echo(&c, 1);
 }
 
 
@@ -517,13 +463,58 @@ qreadcons(Queue *q, char *buf, int n)
 	return qread(q, buf, n);
 }
 
+static long
+consreadkbdline(void *buf, long n)
+{
+	char ch;
+	int eol;
+
+	while(!qcanread(lineq)){
+		eol = 1;
+		if(qreadcons(kbdq, &ch, 1) == 1){
+			eol = 0;
+			kbd.line[kbd.x] = ch;
+			switch(ch){
+			case '\b':
+				if(kbd.x > 0){
+					kbd.x--;
+					/* attempt deleting a codepoint */
+					while(kbd.x > 0 && kbd.line[kbd.x] < (char)-0x40)
+						kbd.x--;
+					/* codepoint == glyph? One can hope... */
+					echochar(ch);
+				}
+				break;
+			case 0x15:
+				kbd.x = 0;
+				break;
+			case '\n':
+				kbd.x++;
+				echochar(ch);
+				/* fallthrough */
+			case 0x04:
+				eol = 1;
+				break;
+			default:
+				kbd.x++;
+				echochar(ch);
+			}
+		}
+		if(kbd.x == sizeof(kbd.line) || eol){
+			qwrite(lineq, kbd.line, kbd.x);
+			kbd.x = 0;
+		}
+	}
+	return qread(lineq, buf, n);
+}
+
 static long
 consread(Chan *c, void *buf, long n, vlong off)
 {
 	char *b;
 	char tmp[128];		/* must be >= 6*NUMSIZE */
 	char *cbuf = buf;
-	int ch, i, eol;
+	int i;
 	vlong offset = off;
 
 	if(n <= 0)
@@ -550,36 +541,8 @@ consread(Chan *c, void *buf, long n, vlong off)
 				} while (n>0 && qcanread(kbdq));
 				n = cbuf - (char*)buf;
 			}
-		} else {
-			while(!qcanread(lineq)) {
-				eol = 1;
-				if(qreadcons(kbdq, &kbd.line[kbd.x], 1) == 1){
-					eol = 0;
-					ch = kbd.line[kbd.x];
-					switch(ch){
-					case '\b':
-						if(kbd.x)
-							kbd.x--;
-						break;
-					case 0x15:
-						kbd.x = 0;
-						break;
-					case '\n':
-						kbd.x++;
-					case 0x04:
-						eol = 1;
-						break;
-					default:
-						kbd.x++;
-					}
-				}
-				if(kbd.x == sizeof(kbd.line) || eol){
-					qwrite(lineq, kbd.line, kbd.x);
-					kbd.x = 0;
-				}
-			}
-			n = qread(lineq, buf, n);
-		}
+		} else
+			n = consreadkbdline(buf, n);
 		qunlock(&kbd.lk);
 		poperror();
 		return n;
diff --git a/kern/devkbd.c b/kern/devkbd.c
index e0921e2..6fe3143 100644
--- a/kern/devkbd.c
+++ b/kern/devkbd.c
@@ -4,9 +4,65 @@
 #include	"fns.h"
 #include	"error.h"
 
+#include 	"keyboard.h"
+
 static Queue*	keyq;
 static int kbdinuse;
 
+static int
+_kbdputc(Queue *q, int c)
+{
+	char buf[UTFmax];
+	Rune r = c;
+	int n;
+
+	if((n = runetochar(buf, &r)) > 0)
+		qproduce(q, buf, n);
+	return 0;
+}
+
+/* _kbdputc, but with compose translation */
+static int
+kbdputc(Queue *q, int c)
+{
+	static int collecting, nk;
+	static Rune kc[5];
+	int i;
+
+	switch(c){
+	case 0:
+	case Kcaps:
+	case Knum:
+	case Kshift:
+	case Kaltgr:
+	case Kmod4:
+	case Kctl:
+		/* ignore modifiers; see nextrune() of kbdfs */
+		return 0;
+
+	case Kalt:
+		collecting = 1;
+		nk = 0;
+		return 0;
+	}
+
+	if(!collecting)
+		return _kbdputc(q, c);
+
+	kc[nk++] = c;
+	c = latin1(kc, nk);
+	if(c < -1)  /* need more keystrokes */
+		return 0;
+	if(c != -1) /* valid sequence */
+		_kbdputc(q, c);
+	else
+		for(i=0; i<nk; i++)
+			_kbdputc(q, kc[i]);
+	nk = 0;
+	collecting = 0;
+	return 0;
+}
+
 void
 kbdkey(Rune r, int down)
 {
@@ -17,7 +73,7 @@ kbdkey(Rune r, int down)
 
 	if(!kbdinuse || keyq == nil){
 		if(down)
-			kbdputc(kbdq, r);	/* /dev/cons */
+			kbdputc(kbdq, r);
 		return;
 	}
 
diff --git a/kern/fns.h b/kern/fns.h
index f267781..e1fa041 100644
--- a/kern/fns.h
+++ b/kern/fns.h
@@ -78,7 +78,6 @@ int		iprint(char*, ...);
 void		isdir(Chan*);
 int		iseve(void);
 #define	islo()	(0)
-int		kbdputc(Queue*, int);
 void		kbdkey(Rune, int);
 int		kproc(char*, void(*)(void*), void*);
 void		ksetenv(char*, char*, int);
-- 
2.44.0


                 reply	other threads:[~2024-04-13  5:00 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

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=CAGOW0YNHHynkjTepTqvvfGfuQTU4ty3nqTyFfjJmcniLCpqRQg@mail.gmail.com \
    --to=amavect@gmail.com \
    --cc=9front@9front.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;
as well as URLs for NNTP newsgroup(s).