diff options
author | cinap_lenrek <cinap_lenrek@gmx.de> | 2013-10-27 19:05:40 +0100 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@gmx.de> | 2013-10-27 19:05:40 +0100 |
commit | b831ec005baf286bb3418c51baf7e5814a940bfa (patch) | |
tree | 55949efa9d3cf42c8813858861a2ea5400196ff2 | |
parent | ecab88b983e779cc7c5824069a993db788f87350 (diff) |
vt: utf-8 support
-rw-r--r-- | sys/src/cmd/vt/cons.h | 5 | ||||
-rw-r--r-- | sys/src/cmd/vt/main.c | 225 | ||||
-rw-r--r-- | sys/src/cmd/vt/vt.c | 19 |
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; |