9front - general discussion about 9front
 help / color / mirror / Atom feed
* [9front] [drawterm] [PATCH] fix backspace deleting login prompt
@ 2024-04-13  4:59 Amavect
  0 siblings, 0 replies; only message in thread
From: Amavect @ 2024-04-13  4:59 UTC (permalink / raw)
  To: 9front

[-- 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


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2024-04-13  5:00 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-04-13  4:59 [9front] [drawterm] [PATCH] fix backspace deleting login prompt Amavect

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).