summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@gmx.de>2013-10-27 19:05:40 +0100
committercinap_lenrek <cinap_lenrek@gmx.de>2013-10-27 19:05:40 +0100
commitb831ec005baf286bb3418c51baf7e5814a940bfa (patch)
tree55949efa9d3cf42c8813858861a2ea5400196ff2
parentecab88b983e779cc7c5824069a993db788f87350 (diff)
vt: utf-8 support
-rw-r--r--sys/src/cmd/vt/cons.h5
-rw-r--r--sys/src/cmd/vt/main.c225
-rw-r--r--sys/src/cmd/vt/vt.c19
3 files changed, 135 insertions, 114 deletions
diff --git a/sys/src/cmd/vt/cons.h b/sys/src/cmd/vt/cons.h
index 436ef6366..a6a445bf6 100644
--- a/sys/src/cmd/vt/cons.h
+++ b/sys/src/cmd/vt/cons.h
@@ -59,14 +59,13 @@ extern void clear(Rectangle);
extern void newline(void);
extern int get_next_char(void);
extern void ringbell(void);
-extern int number(char *, int *);
+extern int number(Rune *, int *);
extern void scroll(int,int,int,int);
extern void backup(int);
extern void sendnchars(int, char *);
-extern void sendnchars2(int, char *);
extern Point pt(int, int);
extern void funckey(int);
-extern void drawstring(Point, char*, int);
+extern void drawstring(Point, Rune*, int);
extern int debug;
extern int yscrmin, yscrmax;
diff --git a/sys/src/cmd/vt/main.c b/sys/src/cmd/vt/main.c
index 0b789be23..aad1828c2 100644
--- a/sys/src/cmd/vt/main.c
+++ b/sys/src/cmd/vt/main.c
@@ -32,7 +32,7 @@ char *menutext3[] = {
/* variables associated with the screen */
int x, y; /* character positions */
-char *backp;
+Rune *backp;
int backc;
int atend;
int nbacklines;
@@ -45,8 +45,8 @@ int peekc;
int cursoron = 1;
Menu menu2;
Menu menu3;
-char *histp;
-char hist[HISTSIZ];
+Rune *histp;
+Rune hist[HISTSIZ];
int yscrmin, yscrmax;
int attr, defattr;
int wctlout;
@@ -99,6 +99,7 @@ Biobuf *snarffp = 0;
char *host_buf;
char *hostp; /* input from host */
+
int host_bsize = 2*BSIZE;
int hostlength; /* amount of input from host */
char echo_input[BSIZE];
@@ -277,7 +278,7 @@ int
get_next_char(void)
{
int c = peekc;
- uchar buf[1];
+
peekc = 0;
if(c > 0)
return(c);
@@ -292,11 +293,9 @@ get_next_char(void)
}
backp = 0;
}
- c = (uchar)waitchar();
- if(c > 0 && logfd >= 0) {
- buf[0] = c;
- write(logfd, buf, 1);
- }
+ c = waitchar();
+ if(c > 0 && logfd >= 0)
+ fprint(logfd, "%C", (Rune)c);
}
*histp++ = c;
if(histp >= &hist[HISTSIZ])
@@ -305,68 +304,89 @@ get_next_char(void)
return(c);
}
+char*
+backrune(char *start, char *cp)
+{
+ char *ep;
+
+ ep = cp;
+ cp -= UTFmax;
+ if(cp < start)
+ cp = start;
+ while(cp < ep){
+ Rune r;
+ int n;
+
+ n = chartorune(&r, cp);
+ if(cp + n >= ep)
+ break;
+ cp += n;
+ }
+ return cp;
+}
+
int
-canon(char *ep, int c)
+canon(char *ep, Rune c)
{
- if(c&0200)
- return(SCROLL);
switch(c) {
- case '\b':
- if(sendp > sendbuf)
- sendp--;
+ case Kdown:
+ case Kpgdown:
+ return SCROLL;
+ case '\b':
+ if(sendp > sendbuf){
+ sendp = backrune(sendbuf, sendp);
*ep++ = '\b';
*ep++ = ' ';
*ep++ = '\b';
- break;
- case 0x15: /* ^U line kill */
- sendp = sendbuf;
- *ep++ = '^';
- *ep++ = 'U';
+ }
+ break;
+ case 0x15: /* ^U line kill */
+ sendp = sendbuf;
+ *ep++ = '^';
+ *ep++ = 'U';
+ *ep++ = '\n';
+ break;
+ case 0x17: /* ^W word kill */
+ while(sendp > sendbuf && !alnum(*sendp)) {
+ sendp = backrune(sendbuf, sendp);
+ *ep++ = '\b';
+ *ep++ = ' ';
+ *ep++ = '\b';
+ }
+ while(sendp > sendbuf && alnum(*sendp)) {
+ sendp = backrune(sendbuf, sendp);
+ *ep++ = '\b';
+ *ep++ = ' ';
+ *ep++ = '\b';
+ }
+ break;
+ case '\177': /* interrupt */
+ sendp = sendbuf;
+ send_interrupt();
+ return(NEWLINE);
+ case '\021': /* quit */
+ case '\r':
+ case '\n':
+ if(sendp < &sendbuf[BSIZE])
+ *sendp++ = '\n';
+ sendnchars((int)(sendp-sendbuf), sendbuf);
+ sendp = sendbuf;
+ if(c == '\n' || c == '\r')
*ep++ = '\n';
- break;
- case 0x17: /* ^W word kill */
- while(sendp > sendbuf && !alnum(*sendp)) {
- *ep++ = '\b';
- *ep++ = ' ';
- *ep++ = '\b';
- sendp--;
- }
- while(sendp > sendbuf && alnum(*sendp)) {
- *ep++ = '\b';
- *ep++ = ' ';
- *ep++ = '\b';
- sendp--;
- }
- break;
- case '\177': /* interrupt */
- sendp = sendbuf;
- send_interrupt();
- return(NEWLINE);
- case '\021': /* quit */
- case '\r':
- case '\n':
- if(sendp < &sendbuf[512])
- *sendp++ = '\n';
- sendnchars((int)(sendp-sendbuf), sendbuf);
- sendp = sendbuf;
- if(c == '\n' || c == '\r') {
- *ep++ = '\n';
- }
+ *ep = 0;
+ return(NEWLINE);
+ case '\004': /* EOT */
+ if(sendp == sendbuf) {
+ sendnchars(0,sendbuf);
*ep = 0;
return(NEWLINE);
- case '\004': /* EOT */
- if(sendp == sendbuf) {
- sendnchars(0,sendbuf);
- *ep = 0;
- return(NEWLINE);
- }
- /* fall through */
- default:
- if(sendp < &sendbuf[512])
- *sendp++ = c;
- *ep++ = c;
- break;
-
+ }
+ /* fall through */
+ default:
+ if(sendp < &sendbuf[BSIZE-UTFmax])
+ sendp += runetochar(sendp, &c);
+ ep += runetochar(ep, &c);
+ break;
}
*ep = 0;
return(OTHER);
@@ -380,7 +400,7 @@ sendfk(char *name)
for(i=0; fk[i].name; i++)
if(strcmp(name, fk[i].name)==0){
- sendnchars2(strlen(fk[i].sequence), fk[i].sequence);
+ sendnchars(strlen(fk[i].sequence), fk[i].sequence);
return;
}
}
@@ -390,13 +410,10 @@ waitchar(void)
{
Event e;
int c;
- char c2;
int newmouse;
int wasblocked;
- int kbdchar = -1;
- char echobuf[3*BSIZE];
- static int lastc = -1;
-
+ Rune kbdchar = 0;
+ char echobuf[4*BSIZE];
for(;;) {
if(resize_flag)
@@ -407,26 +424,31 @@ waitchar(void)
if(ecanmouse() && (button2() || button3()))
readmenu();
if(snarffp) {
- if((c = Bgetc(snarffp)) < 0) {
+ static Rune lastc = ~0;
+
+ if((c = Bgetrune(snarffp)) < 0) {
if(lastc != '\n')
write(outfd,"\n",1);
Bterm(snarffp);
snarffp = 0;
if(lastc != '\n') {
- lastc = -1;
+ lastc = ~0;
return('\n');
}
- lastc = -1;
+ lastc = ~0;
continue;
}
lastc = c;
- c2 = c;
- write(outfd, &c2, 1);
+ write(outfd, echobuf, runetochar(echobuf, &lastc));
return(c);
}
if(!blocked && host_avail())
return(rcvchar());
if(kbdchar > 0) {
+ if(backc){
+ backc = 0;
+ backup(backc);
+ }
if(blocked)
resize();
if(cs->raw) {
@@ -494,8 +516,7 @@ waitchar(void)
sendnchars(1, echobuf);
break;
default:
- echobuf[0] = kbdchar;
- sendnchars(1, echobuf);
+ sendnchars(runetochar(echobuf, &kbdchar), echobuf);
break;
}
} else if(canon(echobuf,kbdchar) == SCROLL) {
@@ -504,7 +525,7 @@ waitchar(void)
} else
strcat(echo_input,echobuf);
blocked = 0;
- kbdchar = -1;
+ kbdchar = 0;
continue;
}
curson(wasblocked); /* turn on cursor while we're waiting */
@@ -682,8 +703,8 @@ readmenu(void)
void
backup(int count)
{
- register n;
- register char *cp;
+ Rune *cp;
+ int n;
eresized(0);
if(count == 0 && !pagemode) {
@@ -747,7 +768,7 @@ bigscroll(void) /* scroll up half a page */
}
int
-number(char *p, int *got)
+number(Rune *p, int *got)
{
int c, n = 0;
@@ -767,13 +788,6 @@ number(char *p, int *got)
void
sendnchars(int n,char *p)
{
- sendnchars2(n, p);
- p[n+1] = 0;
-}
-
-void
-sendnchars2(int n,char *p)
-{
if(write(outfd,p,n) < 0) {
close(outfd);
close(0);
@@ -786,35 +800,44 @@ sendnchars2(int n,char *p)
int
host_avail(void)
{
- return(*echop || ((hostp - host_buf) < hostlength));
+ if(*echop != 0 && fullrune(echop, strlen(echop)))
+ return 1;
+ if((hostp - host_buf) < hostlength)
+ return fullrune(hostp, hostlength - (hostp - host_buf));
+ return 0;
}
int
rcvchar(void)
{
- int c;
- if(*echop) {
- c = *echop++;
- if(!*echop) {
+ Rune r;
+
+ if(*echop != 0) {
+ echop += chartorune(&r, echop);
+ if(*echop == 0) {
echop = echo_input;
*echop = 0;
}
- return c;
+ return r;
}
- return *hostp++;
+ hostp += chartorune(&r, hostp);
+ return r;
}
void
set_host(Event *e)
{
- hostlength = e->n;
+ hostlength -= (hostp - host_buf);
+ if(hostlength > 0)
+ memmove(host_buf, hostp, hostlength);
+ hostlength += e->n;
if(hostlength >= host_bsize) {
host_bsize = BSIZE*((hostlength + BSIZE)/BSIZE);
- host_buf = realloc(host_buf,host_bsize);
+ host_buf = realloc(host_buf, host_bsize);
}
+ memmove(host_buf + hostlength - e->n, e->data, e->n);
+ host_buf[hostlength] = 0;
hostp = host_buf;
- memmove(host_buf,e->data,hostlength);
- host_buf[hostlength]=0;
}
void
@@ -854,12 +877,12 @@ funckey(int key)
return;
if(fk[key].name == 0)
return;
- sendnchars2(strlen(fk[key].sequence), fk[key].sequence);
+ sendnchars(strlen(fk[key].sequence), fk[key].sequence);
}
void
-drawstring(Point p, char *str, int attr)
+drawstring(Point p, Rune *str, int attr)
{
int i;
Image *txt, *bg, *tmp;
@@ -877,6 +900,6 @@ drawstring(Point p, char *str, int attr)
txt = hicolors[i];
}
- draw(screen, Rpt(p, addpt(p, stringsize(font, str))), bg, nil, p);
- string(screen, p, txt, ZP, font, str);
+ draw(screen, Rpt(p, addpt(p, runestringsize(font, str))), bg, nil, p);
+ runestring(screen, p, txt, ZP, font, str);
}
diff --git a/sys/src/cmd/vt/vt.c b/sys/src/cmd/vt/vt.c
index c1040a05f..b63d8e2cd 100644
--- a/sys/src/cmd/vt/vt.c
+++ b/sys/src/cmd/vt/vt.c
@@ -133,7 +133,7 @@ fixops(int *operand)
void
emulate(void)
{
- char buf[BUFS+1];
+ Rune buf[BUFS+1];
int i;
int n;
int c;
@@ -328,8 +328,8 @@ print("resetterminal\n");
*/
case 'Z':
Ident:
- sendnchars2(7, "\033[?1;2c"); /* VT100 with AVO option */
-// sendnchars2(5, "\033[?6c"); /* VT102 (insert/delete-char, etc.) */
+ sendnchars(7, "\033[?1;2c"); /* VT100 with AVO option */
+// sendnchars(5, "\033[?6c"); /* VT102 (insert/delete-char, etc.) */
break;
/*
@@ -532,11 +532,11 @@ print("resetterminal\n");
case 'n':
switch(operand[0]){
case 5: /* status */
- sendnchars2(4, "\033[0n"); /* terminal ok */
+ sendnchars(4, "\033[0n"); /* terminal ok */
break;
case 6: /* cursor position */
- sendnchars2(sprint(buf, "\033[%d;%dR",
- originrelative ? y+1 - yscrmin : y+1, x+1), buf);
+ sendnchars(sprint((char*)buf, "\033[%d;%dR",
+ originrelative ? y+1 - yscrmin : y+1, x+1), (char*)buf);
break;
}
break;
@@ -573,7 +573,7 @@ print("resetterminal\n");
* x - report terminal parameters
*/
case 'x':
- sendnchars2(20, "\033[3;1;1;120;120;1;0x");
+ sendnchars(20, "\033[3;1;1;120;120;1;0x");
break;
/*
@@ -847,8 +847,8 @@ print("unknown command '%c' (0x%x)\n", dch, dch);
default: /* ordinary char */
Default:
- if(isgraphics && gmap[(uchar) buf[0]])
- buf[0] = gmap[(uchar) buf[0]];
+ if(isgraphics && buf[0] < nelem(gmap) && gmap[buf[0]])
+ buf[0] = gmap[buf[0]];
/* line wrap */
if (x > xmax){
@@ -867,7 +867,6 @@ Default:
c = 0;
}
buf[n] = 0;
-// clear(Rpt(pt(x,y), pt(x+n, y+1)));
drawstring(pt(x, y), buf, attr);
x += n;
peekc = c;