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