vt: utf-8 support
This commit is contained in:
parent
ecab88b983
commit
b831ec005b
3 changed files with 136 additions and 115 deletions
|
@ -59,14 +59,13 @@ extern void clear(Rectangle);
|
||||||
extern void newline(void);
|
extern void newline(void);
|
||||||
extern int get_next_char(void);
|
extern int get_next_char(void);
|
||||||
extern void ringbell(void);
|
extern void ringbell(void);
|
||||||
extern int number(char *, int *);
|
extern int number(Rune *, int *);
|
||||||
extern void scroll(int,int,int,int);
|
extern void scroll(int,int,int,int);
|
||||||
extern void backup(int);
|
extern void backup(int);
|
||||||
extern void sendnchars(int, char *);
|
extern void sendnchars(int, char *);
|
||||||
extern void sendnchars2(int, char *);
|
|
||||||
extern Point pt(int, int);
|
extern Point pt(int, int);
|
||||||
extern void funckey(int);
|
extern void funckey(int);
|
||||||
extern void drawstring(Point, char*, int);
|
extern void drawstring(Point, Rune*, int);
|
||||||
|
|
||||||
extern int debug;
|
extern int debug;
|
||||||
extern int yscrmin, yscrmax;
|
extern int yscrmin, yscrmax;
|
||||||
|
|
|
@ -32,7 +32,7 @@ char *menutext3[] = {
|
||||||
/* variables associated with the screen */
|
/* variables associated with the screen */
|
||||||
|
|
||||||
int x, y; /* character positions */
|
int x, y; /* character positions */
|
||||||
char *backp;
|
Rune *backp;
|
||||||
int backc;
|
int backc;
|
||||||
int atend;
|
int atend;
|
||||||
int nbacklines;
|
int nbacklines;
|
||||||
|
@ -45,8 +45,8 @@ int peekc;
|
||||||
int cursoron = 1;
|
int cursoron = 1;
|
||||||
Menu menu2;
|
Menu menu2;
|
||||||
Menu menu3;
|
Menu menu3;
|
||||||
char *histp;
|
Rune *histp;
|
||||||
char hist[HISTSIZ];
|
Rune hist[HISTSIZ];
|
||||||
int yscrmin, yscrmax;
|
int yscrmin, yscrmax;
|
||||||
int attr, defattr;
|
int attr, defattr;
|
||||||
int wctlout;
|
int wctlout;
|
||||||
|
@ -99,6 +99,7 @@ Biobuf *snarffp = 0;
|
||||||
|
|
||||||
char *host_buf;
|
char *host_buf;
|
||||||
char *hostp; /* input from host */
|
char *hostp; /* input from host */
|
||||||
|
|
||||||
int host_bsize = 2*BSIZE;
|
int host_bsize = 2*BSIZE;
|
||||||
int hostlength; /* amount of input from host */
|
int hostlength; /* amount of input from host */
|
||||||
char echo_input[BSIZE];
|
char echo_input[BSIZE];
|
||||||
|
@ -277,7 +278,7 @@ int
|
||||||
get_next_char(void)
|
get_next_char(void)
|
||||||
{
|
{
|
||||||
int c = peekc;
|
int c = peekc;
|
||||||
uchar buf[1];
|
|
||||||
peekc = 0;
|
peekc = 0;
|
||||||
if(c > 0)
|
if(c > 0)
|
||||||
return(c);
|
return(c);
|
||||||
|
@ -292,11 +293,9 @@ get_next_char(void)
|
||||||
}
|
}
|
||||||
backp = 0;
|
backp = 0;
|
||||||
}
|
}
|
||||||
c = (uchar)waitchar();
|
c = waitchar();
|
||||||
if(c > 0 && logfd >= 0) {
|
if(c > 0 && logfd >= 0)
|
||||||
buf[0] = c;
|
fprint(logfd, "%C", (Rune)c);
|
||||||
write(logfd, buf, 1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
*histp++ = c;
|
*histp++ = c;
|
||||||
if(histp >= &hist[HISTSIZ])
|
if(histp >= &hist[HISTSIZ])
|
||||||
|
@ -305,18 +304,41 @@ get_next_char(void)
|
||||||
return(c);
|
return(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
char*
|
||||||
canon(char *ep, int c)
|
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, Rune c)
|
||||||
{
|
{
|
||||||
if(c&0200)
|
|
||||||
return(SCROLL);
|
|
||||||
switch(c) {
|
switch(c) {
|
||||||
|
case Kdown:
|
||||||
|
case Kpgdown:
|
||||||
|
return SCROLL;
|
||||||
case '\b':
|
case '\b':
|
||||||
if(sendp > sendbuf)
|
if(sendp > sendbuf){
|
||||||
sendp--;
|
sendp = backrune(sendbuf, sendp);
|
||||||
*ep++ = '\b';
|
*ep++ = '\b';
|
||||||
*ep++ = ' ';
|
*ep++ = ' ';
|
||||||
*ep++ = '\b';
|
*ep++ = '\b';
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 0x15: /* ^U line kill */
|
case 0x15: /* ^U line kill */
|
||||||
sendp = sendbuf;
|
sendp = sendbuf;
|
||||||
|
@ -326,16 +348,16 @@ canon(char *ep, int c)
|
||||||
break;
|
break;
|
||||||
case 0x17: /* ^W word kill */
|
case 0x17: /* ^W word kill */
|
||||||
while(sendp > sendbuf && !alnum(*sendp)) {
|
while(sendp > sendbuf && !alnum(*sendp)) {
|
||||||
|
sendp = backrune(sendbuf, sendp);
|
||||||
*ep++ = '\b';
|
*ep++ = '\b';
|
||||||
*ep++ = ' ';
|
*ep++ = ' ';
|
||||||
*ep++ = '\b';
|
*ep++ = '\b';
|
||||||
sendp--;
|
|
||||||
}
|
}
|
||||||
while(sendp > sendbuf && alnum(*sendp)) {
|
while(sendp > sendbuf && alnum(*sendp)) {
|
||||||
|
sendp = backrune(sendbuf, sendp);
|
||||||
*ep++ = '\b';
|
*ep++ = '\b';
|
||||||
*ep++ = ' ';
|
*ep++ = ' ';
|
||||||
*ep++ = '\b';
|
*ep++ = '\b';
|
||||||
sendp--;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case '\177': /* interrupt */
|
case '\177': /* interrupt */
|
||||||
|
@ -345,13 +367,12 @@ canon(char *ep, int c)
|
||||||
case '\021': /* quit */
|
case '\021': /* quit */
|
||||||
case '\r':
|
case '\r':
|
||||||
case '\n':
|
case '\n':
|
||||||
if(sendp < &sendbuf[512])
|
if(sendp < &sendbuf[BSIZE])
|
||||||
*sendp++ = '\n';
|
*sendp++ = '\n';
|
||||||
sendnchars((int)(sendp-sendbuf), sendbuf);
|
sendnchars((int)(sendp-sendbuf), sendbuf);
|
||||||
sendp = sendbuf;
|
sendp = sendbuf;
|
||||||
if(c == '\n' || c == '\r') {
|
if(c == '\n' || c == '\r')
|
||||||
*ep++ = '\n';
|
*ep++ = '\n';
|
||||||
}
|
|
||||||
*ep = 0;
|
*ep = 0;
|
||||||
return(NEWLINE);
|
return(NEWLINE);
|
||||||
case '\004': /* EOT */
|
case '\004': /* EOT */
|
||||||
|
@ -362,11 +383,10 @@ canon(char *ep, int c)
|
||||||
}
|
}
|
||||||
/* fall through */
|
/* fall through */
|
||||||
default:
|
default:
|
||||||
if(sendp < &sendbuf[512])
|
if(sendp < &sendbuf[BSIZE-UTFmax])
|
||||||
*sendp++ = c;
|
sendp += runetochar(sendp, &c);
|
||||||
*ep++ = c;
|
ep += runetochar(ep, &c);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
*ep = 0;
|
*ep = 0;
|
||||||
return(OTHER);
|
return(OTHER);
|
||||||
|
@ -380,7 +400,7 @@ sendfk(char *name)
|
||||||
|
|
||||||
for(i=0; fk[i].name; i++)
|
for(i=0; fk[i].name; i++)
|
||||||
if(strcmp(name, fk[i].name)==0){
|
if(strcmp(name, fk[i].name)==0){
|
||||||
sendnchars2(strlen(fk[i].sequence), fk[i].sequence);
|
sendnchars(strlen(fk[i].sequence), fk[i].sequence);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -390,13 +410,10 @@ waitchar(void)
|
||||||
{
|
{
|
||||||
Event e;
|
Event e;
|
||||||
int c;
|
int c;
|
||||||
char c2;
|
|
||||||
int newmouse;
|
int newmouse;
|
||||||
int wasblocked;
|
int wasblocked;
|
||||||
int kbdchar = -1;
|
Rune kbdchar = 0;
|
||||||
char echobuf[3*BSIZE];
|
char echobuf[4*BSIZE];
|
||||||
static int lastc = -1;
|
|
||||||
|
|
||||||
|
|
||||||
for(;;) {
|
for(;;) {
|
||||||
if(resize_flag)
|
if(resize_flag)
|
||||||
|
@ -407,26 +424,31 @@ waitchar(void)
|
||||||
if(ecanmouse() && (button2() || button3()))
|
if(ecanmouse() && (button2() || button3()))
|
||||||
readmenu();
|
readmenu();
|
||||||
if(snarffp) {
|
if(snarffp) {
|
||||||
if((c = Bgetc(snarffp)) < 0) {
|
static Rune lastc = ~0;
|
||||||
|
|
||||||
|
if((c = Bgetrune(snarffp)) < 0) {
|
||||||
if(lastc != '\n')
|
if(lastc != '\n')
|
||||||
write(outfd,"\n",1);
|
write(outfd,"\n",1);
|
||||||
Bterm(snarffp);
|
Bterm(snarffp);
|
||||||
snarffp = 0;
|
snarffp = 0;
|
||||||
if(lastc != '\n') {
|
if(lastc != '\n') {
|
||||||
lastc = -1;
|
lastc = ~0;
|
||||||
return('\n');
|
return('\n');
|
||||||
}
|
}
|
||||||
lastc = -1;
|
lastc = ~0;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
lastc = c;
|
lastc = c;
|
||||||
c2 = c;
|
write(outfd, echobuf, runetochar(echobuf, &lastc));
|
||||||
write(outfd, &c2, 1);
|
|
||||||
return(c);
|
return(c);
|
||||||
}
|
}
|
||||||
if(!blocked && host_avail())
|
if(!blocked && host_avail())
|
||||||
return(rcvchar());
|
return(rcvchar());
|
||||||
if(kbdchar > 0) {
|
if(kbdchar > 0) {
|
||||||
|
if(backc){
|
||||||
|
backc = 0;
|
||||||
|
backup(backc);
|
||||||
|
}
|
||||||
if(blocked)
|
if(blocked)
|
||||||
resize();
|
resize();
|
||||||
if(cs->raw) {
|
if(cs->raw) {
|
||||||
|
@ -494,8 +516,7 @@ waitchar(void)
|
||||||
sendnchars(1, echobuf);
|
sendnchars(1, echobuf);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
echobuf[0] = kbdchar;
|
sendnchars(runetochar(echobuf, &kbdchar), echobuf);
|
||||||
sendnchars(1, echobuf);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else if(canon(echobuf,kbdchar) == SCROLL) {
|
} else if(canon(echobuf,kbdchar) == SCROLL) {
|
||||||
|
@ -504,7 +525,7 @@ waitchar(void)
|
||||||
} else
|
} else
|
||||||
strcat(echo_input,echobuf);
|
strcat(echo_input,echobuf);
|
||||||
blocked = 0;
|
blocked = 0;
|
||||||
kbdchar = -1;
|
kbdchar = 0;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
curson(wasblocked); /* turn on cursor while we're waiting */
|
curson(wasblocked); /* turn on cursor while we're waiting */
|
||||||
|
@ -682,8 +703,8 @@ readmenu(void)
|
||||||
void
|
void
|
||||||
backup(int count)
|
backup(int count)
|
||||||
{
|
{
|
||||||
register n;
|
Rune *cp;
|
||||||
register char *cp;
|
int n;
|
||||||
|
|
||||||
eresized(0);
|
eresized(0);
|
||||||
if(count == 0 && !pagemode) {
|
if(count == 0 && !pagemode) {
|
||||||
|
@ -747,7 +768,7 @@ bigscroll(void) /* scroll up half a page */
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
number(char *p, int *got)
|
number(Rune *p, int *got)
|
||||||
{
|
{
|
||||||
int c, n = 0;
|
int c, n = 0;
|
||||||
|
|
||||||
|
@ -766,13 +787,6 @@ number(char *p, int *got)
|
||||||
|
|
||||||
void
|
void
|
||||||
sendnchars(int n,char *p)
|
sendnchars(int n,char *p)
|
||||||
{
|
|
||||||
sendnchars2(n, p);
|
|
||||||
p[n+1] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
sendnchars2(int n,char *p)
|
|
||||||
{
|
{
|
||||||
if(write(outfd,p,n) < 0) {
|
if(write(outfd,p,n) < 0) {
|
||||||
close(outfd);
|
close(outfd);
|
||||||
|
@ -786,35 +800,44 @@ sendnchars2(int n,char *p)
|
||||||
int
|
int
|
||||||
host_avail(void)
|
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
|
int
|
||||||
rcvchar(void)
|
rcvchar(void)
|
||||||
{
|
{
|
||||||
int c;
|
Rune r;
|
||||||
if(*echop) {
|
|
||||||
c = *echop++;
|
if(*echop != 0) {
|
||||||
if(!*echop) {
|
echop += chartorune(&r, echop);
|
||||||
|
if(*echop == 0) {
|
||||||
echop = echo_input;
|
echop = echo_input;
|
||||||
*echop = 0;
|
*echop = 0;
|
||||||
}
|
}
|
||||||
return c;
|
return r;
|
||||||
}
|
}
|
||||||
return *hostp++;
|
hostp += chartorune(&r, hostp);
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
set_host(Event *e)
|
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) {
|
if(hostlength >= host_bsize) {
|
||||||
host_bsize = BSIZE*((hostlength + BSIZE)/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;
|
hostp = host_buf;
|
||||||
memmove(host_buf,e->data,hostlength);
|
|
||||||
host_buf[hostlength]=0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -854,12 +877,12 @@ funckey(int key)
|
||||||
return;
|
return;
|
||||||
if(fk[key].name == 0)
|
if(fk[key].name == 0)
|
||||||
return;
|
return;
|
||||||
sendnchars2(strlen(fk[key].sequence), fk[key].sequence);
|
sendnchars(strlen(fk[key].sequence), fk[key].sequence);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
drawstring(Point p, char *str, int attr)
|
drawstring(Point p, Rune *str, int attr)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
Image *txt, *bg, *tmp;
|
Image *txt, *bg, *tmp;
|
||||||
|
@ -877,6 +900,6 @@ drawstring(Point p, char *str, int attr)
|
||||||
txt = hicolors[i];
|
txt = hicolors[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
draw(screen, Rpt(p, addpt(p, stringsize(font, str))), bg, nil, p);
|
draw(screen, Rpt(p, addpt(p, runestringsize(font, str))), bg, nil, p);
|
||||||
string(screen, p, txt, ZP, font, str);
|
runestring(screen, p, txt, ZP, font, str);
|
||||||
}
|
}
|
||||||
|
|
|
@ -133,7 +133,7 @@ fixops(int *operand)
|
||||||
void
|
void
|
||||||
emulate(void)
|
emulate(void)
|
||||||
{
|
{
|
||||||
char buf[BUFS+1];
|
Rune buf[BUFS+1];
|
||||||
int i;
|
int i;
|
||||||
int n;
|
int n;
|
||||||
int c;
|
int c;
|
||||||
|
@ -328,8 +328,8 @@ print("resetterminal\n");
|
||||||
*/
|
*/
|
||||||
case 'Z':
|
case 'Z':
|
||||||
Ident:
|
Ident:
|
||||||
sendnchars2(7, "\033[?1;2c"); /* VT100 with AVO option */
|
sendnchars(7, "\033[?1;2c"); /* VT100 with AVO option */
|
||||||
// sendnchars2(5, "\033[?6c"); /* VT102 (insert/delete-char, etc.) */
|
// sendnchars(5, "\033[?6c"); /* VT102 (insert/delete-char, etc.) */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -532,11 +532,11 @@ print("resetterminal\n");
|
||||||
case 'n':
|
case 'n':
|
||||||
switch(operand[0]){
|
switch(operand[0]){
|
||||||
case 5: /* status */
|
case 5: /* status */
|
||||||
sendnchars2(4, "\033[0n"); /* terminal ok */
|
sendnchars(4, "\033[0n"); /* terminal ok */
|
||||||
break;
|
break;
|
||||||
case 6: /* cursor position */
|
case 6: /* cursor position */
|
||||||
sendnchars2(sprint(buf, "\033[%d;%dR",
|
sendnchars(sprint((char*)buf, "\033[%d;%dR",
|
||||||
originrelative ? y+1 - yscrmin : y+1, x+1), buf);
|
originrelative ? y+1 - yscrmin : y+1, x+1), (char*)buf);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -573,7 +573,7 @@ print("resetterminal\n");
|
||||||
* x - report terminal parameters
|
* x - report terminal parameters
|
||||||
*/
|
*/
|
||||||
case 'x':
|
case 'x':
|
||||||
sendnchars2(20, "\033[3;1;1;120;120;1;0x");
|
sendnchars(20, "\033[3;1;1;120;120;1;0x");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -847,8 +847,8 @@ print("unknown command '%c' (0x%x)\n", dch, dch);
|
||||||
|
|
||||||
default: /* ordinary char */
|
default: /* ordinary char */
|
||||||
Default:
|
Default:
|
||||||
if(isgraphics && gmap[(uchar) buf[0]])
|
if(isgraphics && buf[0] < nelem(gmap) && gmap[buf[0]])
|
||||||
buf[0] = gmap[(uchar) buf[0]];
|
buf[0] = gmap[buf[0]];
|
||||||
|
|
||||||
/* line wrap */
|
/* line wrap */
|
||||||
if (x > xmax){
|
if (x > xmax){
|
||||||
|
@ -867,7 +867,6 @@ Default:
|
||||||
c = 0;
|
c = 0;
|
||||||
}
|
}
|
||||||
buf[n] = 0;
|
buf[n] = 0;
|
||||||
// clear(Rpt(pt(x,y), pt(x+n, y+1)));
|
|
||||||
drawstring(pt(x, y), buf, attr);
|
drawstring(pt(x, y), buf, attr);
|
||||||
x += n;
|
x += n;
|
||||||
peekc = c;
|
peekc = c;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue