From 7f0f4210b60b912032737146fb036cefd71d670b Mon Sep 17 00:00:00 2001 From: Amavect 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 #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 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