M port/devcons.c => port/devcons.c +24 -17
@@ 209,15 209,14 @@ prflush(void)
}
void
-echo(int c)
+echo(Rune r, char *buf, int n)
{
- char ch;
static int ctrlt;
/*
* ^p hack
*/
- if(c==0x10 && conf.cntrlp)
+ if(r==0x10 && conf.cntrlp)
panic("^p");
/*
@@ 225,7 224,7 @@ echo(int c)
*/
if(ctrlt == 2){
ctrlt = 0;
- switch(c){
+ switch(r){
case 0x14:
break; /* pass it on */
case 'm':
@@ 241,19 240,17 @@ echo(int c)
exit();
break;
}
- }else if(c == 0x14){
+ }else if(r == 0x14){
ctrlt++;
return;
}
ctrlt = 0;
if(raw.ref)
return;
- if(c == 0x15)
+ if(r == 0x15)
putstrn("^U\n", 3);
- else{
- ch = c;
- putstrn(&ch, 1);
- }
+ else
+ putstrn(buf, n);
}
/*
@@ 268,19 265,29 @@ kbdcr2nl(IOQ *q, int ch)
}
/*
- * Put character into read queue at interrupt time.
+ * Put character, possibly a rune, into read queue at interrupt time.
* Always called splhi from processor 0.
*/
int
kbdputc(IOQ *q, int ch)
{
+ int i, n;
+ char buf[3];
+ Rune r;
+
USED(q);
- echo(ch);
- kbdq.c = ch;
- *kbdq.in++ = ch;
- if(kbdq.in == kbdq.buf+sizeof(kbdq.buf))
- kbdq.in = kbdq.buf;
- if(raw.ref || ch=='\n' || ch==0x04)
+ r = ch;
+ n = runetochar(buf, &r);
+ if(n == 0)
+ return 0;
+ echo(r, buf, n);
+ kbdq.c = r;
+ for(i=0; i<n; i++){
+ *kbdq.in++ = buf[i];
+ if(kbdq.in == kbdq.buf+sizeof(kbdq.buf))
+ kbdq.in = kbdq.buf;
+ }
+ if(raw.ref || r=='\n' || r==0x04)
wakeup(&kbdq.r);
return 0;
}
M port/lib.h => port/lib.h +7 -0
@@ 25,6 25,13 @@ extern long strlen(char*);
extern int atoi(char*);
/*
+ * rune routines
+ */
+extern int runetochar(char*, Rune*);
+extern int chartorune(Rune*, char*);
+extern int countrune(char*);
+
+/*
* print routines
*/
M power/u.h => power/u.h +1 -0
@@ 3,6 3,7 @@ typedef unsigned char uchar;
typedef unsigned long ulong;
typedef long vlong;
typedef union Length Length;
+typedef ushort Rune;
union Length
{
M ss/screen.c => ss/screen.c +38 -2
@@ 78,8 78,44 @@ screenputc(int c)
void
screenputs(char *s, int n)
{
- while(n-- > 0)
- screenputc(*s++);
+ Rune r;
+ int i;
+ char buf[4];
+
+ while(n > 0){
+ i = chartorune(&r, s);
+ if(i == 0){
+ s++;
+ --n;
+ continue;
+ }
+ memmove(buf, s, i);
+ buf[i] = 0;
+ n -= i;
+ s += i;
+ if(r == '\n'){
+ out.pos.x = MINX;
+ out.pos.y += defont0.height;
+ if(out.pos.y > gscreen.r.max.y-defont0.height)
+ out.pos.y = gscreen.r.min.y;
+ gbitblt(&gscreen, Pt(0, out.pos.y), &gscreen,
+ Rect(0, out.pos.y, gscreen.r.max.x, out.pos.y+2*defont0.height), 0);
+ }else if(r == '\t'){
+ out.pos.x += (8-((out.pos.x-MINX)/out.bwid&7))*out.bwid;
+ if(out.pos.x >= gscreen.r.max.x)
+ screenputs("\n", 1);
+ }else if(r == '\b'){
+ if(out.pos.x >= out.bwid+MINX){
+ out.pos.x -= out.bwid;
+ screenputs(" ", 1);
+ out.pos.x -= out.bwid;
+ }
+ }else{
+ if(out.pos.x >= gscreen.r.max.x-out.bwid)
+ screenputs("\n", 1);
+ out.pos = gstring(&gscreen, out.pos, defont, buf, S);
+ }
+ }
}
/*
M ss/u.h => ss/u.h +1 -0
@@ 3,6 3,7 @@ typedef unsigned char uchar;
typedef unsigned long ulong;
typedef long vlong;
typedef union Length Length;
+typedef ushort Rune;
union Length
{