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 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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
int
|
||||
canon(char *ep, int 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, 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;
|
||||
|
||||
|
@ -766,13 +787,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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue