vt: make it fast

This commit is contained in:
cinap_lenrek 2017-04-19 01:46:20 +02:00
parent db729cbb50
commit 219050cc36
3 changed files with 144 additions and 149 deletions

View file

@ -10,8 +10,8 @@ extern Consstate* cs;
#define INSET 2 #define INSET 2
#define BUFS 32 #define BUFS 32
#define HISTSIZ 65536 /* number of history characters */ #define HISTSIZ (64*1024) /* number of history characters */
#define BSIZE 1000 #define BSIZE (8*1024)
#define SCROLL 2 #define SCROLL 2
#define NEWLINE 1 #define NEWLINE 1
@ -22,17 +22,13 @@ extern Consstate* cs;
/* text attributes */ /* text attributes */
enum { enum {
THighIntensity = (1<<0), THighIntensity = 1<<0,
TUnderline = (1<<1), TUnderline = 1<<1,
TBlink = (1<<2), TBlink = 1<<2,
TReverse = (1<<3), TReverse = 1<<3,
TInvisible = (1<<4), TInvisible = 1<<4,
}; };
#define button1() ((mouse.buttons & 07)==1)
#define button2() ((mouse.buttons & 07)==2)
#define button3() ((mouse.buttons & 07)==4)
struct ttystate { struct ttystate {
int crnl; int crnl;
int nlcr; int nlcr;
@ -64,9 +60,8 @@ extern void sendnchars(int, char *);
extern Point pt(int, int); extern Point pt(int, int);
extern Point pos(Point); extern Point pos(Point);
extern void funckey(int); extern void funckey(int);
extern void drawstring(Rune*, int, int); extern void drawstring(Rune*, int);
extern int debug;
extern int yscrmin, yscrmax; extern int yscrmin, yscrmax;
extern int attr; extern int attr;
extern int defattr; extern int defattr;
@ -75,13 +70,9 @@ extern Image *fgcolor;
extern Image *bgcolor; extern Image *bgcolor;
extern Image *colors[]; extern Image *colors[];
extern Image *hicolors[]; extern Image *hicolors[];
extern Image *bgdefault;
extern Image *fgdefault;
extern int cursoron; extern int cursoron;
extern int nocolor; extern int nocolor;
extern void curson(void);
extern void cursoff(void);
extern void setdim(int, int); extern void setdim(int, int);

View file

@ -44,21 +44,19 @@ Menu menu2;
Menu menu3; Menu menu3;
Rune *histp; Rune *histp;
Rune hist[HISTSIZ]; Rune hist[HISTSIZ];
Rune *onscreen; Rune *onscreenrbuf;
uchar *onscreenabuf;
uchar *onscreencbuf;
int yscrmin, yscrmax; int yscrmin, yscrmax;
int attr, defattr; int attr, defattr;
int wctlout;
Image *bordercol; Image *bordercol;
Image *cursback;
Image *colors[8]; Image *colors[8];
Image *hicolors[8]; Image *hicolors[8];
Image *red; Image *red;
Image *green; Image *green;
Image *fgcolor; Image *fgcolor;
Image *bgcolor; Image *bgcolor;
Image *fgdefault;
Image *bgdefault;
Image *highlight; Image *highlight;
uint rgbacolors[8] = { uint rgbacolors[8] = {
@ -91,15 +89,17 @@ int CW;
int XMARGIN; int XMARGIN;
int YMARGIN; int YMARGIN;
Mouse mouse;
Rune kbdchar; Rune kbdchar;
#define button1() ((mc->buttons & 07)==1)
#define button2() ((mc->buttons & 07)==2)
#define button3() ((mc->buttons & 07)==4)
Mousectl *mc; Mousectl *mc;
Keyboardctl *kc; Keyboardctl *kc;
Channel *hc; Channel *hc;
Consstate *cs; Consstate *cs;
int debug;
int nocolor; int nocolor;
int logfd = -1; int logfd = -1;
int hostfd = -1; int hostfd = -1;
@ -126,7 +126,6 @@ void resize(void);
void send_interrupt(void); void send_interrupt(void);
int alnum(int); int alnum(int);
void escapedump(int,uchar *,int); void escapedump(int,uchar *,int);
Rune* onscreenp(int, int);
int int
start_host(void) start_host(void)
@ -219,6 +218,7 @@ initialize(int argc, char **argv)
fk = vt100fk; fk = vt100fk;
blkbg = nocolor = 0; blkbg = nocolor = 0;
rflag = 0; rflag = 0;
attr = defattr;
ARGBEGIN{ ARGBEGIN{
case '2': case '2':
term = "vt220"; term = "vt220";
@ -276,7 +276,6 @@ initialize(int argc, char **argv)
red = allocimage(display, Rect(0,0,1,1), screen->chan, 1, DRed); red = allocimage(display, Rect(0,0,1,1), screen->chan, 1, DRed);
green = allocimage(display, Rect(0,0,1,1), screen->chan, 1, DGreen); green = allocimage(display, Rect(0,0,1,1), screen->chan, 1, DGreen);
bordercol = allocimage(display, Rect(0,0,1,1), screen->chan, 1, 0xCCCCCCCC); bordercol = allocimage(display, Rect(0,0,1,1), screen->chan, 1, 0xCCCCCCCC);
cursback = allocimage(display, Rect(0, 0, CW+1, NS+1), screen->chan, 0, DNofill);
highlight = allocimage(display, Rect(0,0,1,1), CHAN1(CAlpha,8), 1, 0x80); highlight = allocimage(display, Rect(0,0,1,1), CHAN1(CAlpha,8), 1, 0x80);
for(i=0; i<8; i++){ for(i=0; i<8; i++){
@ -285,15 +284,11 @@ initialize(int argc, char **argv)
hicolors[i] = allocimage(display, Rect(0,0,1,1), screen->chan, 1, hicolors[i] = allocimage(display, Rect(0,0,1,1), screen->chan, 1,
rgbahicolors[i]); rgbahicolors[i]);
} }
bgcolor = (blkbg? display->black: display->white);
bgdefault = (blkbg? display->black: display->white); fgcolor = (blkbg? display->white: display->black);
fgdefault = (blkbg? display->white: display->black);
bgcolor = bgdefault;
fgcolor = fgdefault;
resize(); resize();
hc = chancreate(sizeof(Rune*), 1); hc = chancreate(sizeof(Rune*), 5);
if((hostfd = start_host()) >= 0) if((hostfd = start_host()) >= 0)
proccreate(hostreader, nil, BSIZE+1024); proccreate(hostreader, nil, BSIZE+1024);
@ -308,15 +303,81 @@ initialize(int argc, char **argv)
} }
} }
#define onscreenr(x, y) &onscreenrbuf[((y)*(xmax+2) + (x))]
#define onscreena(x, y) &onscreenabuf[((y)*(xmax+2) + (x))]
#define onscreenc(x, y) &onscreencbuf[((y)*(xmax+2) + (x))]
#define bgcol(a, c) (((a)&TReverse)!=0 ? (c)>>4 : (c&15))
#define fgcol(a, c) ((((a)&TReverse)==0 ? (c)>>4 : (c&15)) | (((a)&THighIntensity)!=0)<<4)
void
drawscreen(void)
{
int x, y, n;
uchar c, *ap, *cp;
Rune *rp;
Point p;
/* draw background */
draw(screen, screen->r, bgcolor, nil, ZP);
for(y = 0; y <= ymax; y++){
for(x = 0; x <= xmax; x += n){
cp = onscreenc(x, y);
if((*cp & 1) == 0){
n = 1;
continue;
}
ap = onscreena(x, y);
c = bgcol(*ap, *cp);
for(n = 1; x+n <= xmax && bgcol(ap[n], cp[n]) == c; n++)
;
p = pt(x, y);
draw(screen, Rpt(p, Pt(p.x+CW, p.y+NS)), colors[c>>1], nil, ZP);
}
}
/* draw foreground */
for(y = 0; y <= ymax; y++){
for(x = 0; x <= xmax; x += n){
rp = onscreenr(x, y);
if(*rp == 0){
n = 1;
continue;
}
ap = onscreena(x, y);
cp = onscreenc(x, y);
c = fgcol(*ap, *cp);
for(n = 1; x+n <= xmax && rp[n] != 0 && fgcol(ap[n], cp[n]) == c; n++)
;
runestringn(screen, pt(x, y),
(c&1) ? (((c&16) ? hicolors : colors)[(c&15)>>1]) : fgcolor,
ZP, font, rp, n);
}
if(*onscreenr(x, y) == 0)
runestringn(screen, pt(x, y),
bordercol,
ZP, font, L">", 1);
}
}
void
drawcursor(void)
{
Image *col = (blocked || hostfd < 0) ? red : bordercol;
border(screen, Rpt(pt(x, y), pt(x+1, y+1)), 2, col, ZP);
}
void void
clear(int x1, int y1, int x2, int y2) clear(int x1, int y1, int x2, int y2)
{ {
draw(screen, Rpt(pt(x1,y1), pt(x2,y2)), bgcolor, nil, ZP);
while(y1 < y2){ while(y1 < y2){
if(x1 < x2) if(x1 < x2){
memset(onscreenp(x1, y1), 0, (x2-x1)*sizeof(Rune)); memset(onscreenr(x1, y1), 0, (x2-x1)*sizeof(Rune));
memset(onscreena(x1, y1), 0, x2-x1);
memset(onscreenc(x1, y1), 0, x2-x1);
}
if(x2 > xmax) if(x2 > xmax)
*onscreenp(xmax+1, y1) = '\n'; *onscreenr(xmax+1, y1) = '\n';
y1++; y1++;
} }
} }
@ -325,7 +386,7 @@ void
newline(void) newline(void)
{ {
if(x > xmax) if(x > xmax)
*onscreenp(xmax+1, y) = 0; /* wrap arround, remove hidden newline */ *onscreenr(xmax+1, y) = 0; /* wrap arround, remove hidden newline */
nbacklines--; nbacklines--;
if(y >= yscrmax) { if(y >= yscrmax) {
y = yscrmax; y = yscrmax;
@ -339,25 +400,6 @@ newline(void)
olines++; olines++;
} }
void
cursoff(void)
{
draw(screen, Rpt(pt(x, y), addpt(pt(x, y), Pt(CW,NS))), cursback, nil, cursback->r.min);
}
void
curson(void)
{
Image *col = (blocked || hostfd < 0) ? red : bordercol;
if(!cursoron){
cursoff();
return;
}
draw(cursback, cursback->r, screen, nil, pt(x, y));
border(screen, Rpt(pt(x, y), addpt(pt(x, y), Pt(CW,NS))), 2, col, ZP);
}
int int
get_next_char(void) get_next_char(void)
{ {
@ -602,8 +644,12 @@ waitchar(void)
if(host_avail()) if(host_avail())
return(rcvchar()); return(rcvchar());
free(hostbuf); free(hostbuf);
hostbuf = hostbufp = nil; hostbufp = hostbuf = nbrecvp(hc);
if(host_avail())
return(rcvchar());
} }
drawscreen();
drawcursor();
waitio(); waitio();
} }
} }
@ -613,16 +659,15 @@ waitio(void)
{ {
enum { AMOUSE, ARESIZE, AKBD, AHOST, AEND, }; enum { AMOUSE, ARESIZE, AKBD, AHOST, AEND, };
Alt a[AEND+1] = { Alt a[AEND+1] = {
{ mc->c, &mouse, CHANRCV }, { mc->c, &mc->Mouse, CHANRCV },
{ mc->resizec, nil, CHANRCV }, { mc->resizec, nil, CHANRCV },
{ kc->c, &kbdchar, CHANRCV }, { kc->c, &kbdchar, CHANRCV },
{ hc, &hostbuf, CHANNOP }, { hc, &hostbuf, CHANNOP },
{ nil, nil, CHANEND }, { nil, nil, CHANEND },
}; };
if(hostbuf == nil) a[AHOST].op = CHANRCV; if(hostbuf == nil) a[AHOST].op = CHANRCV;
Next:
curson(); /* turn on cursor while we're waiting */ if(display->bufp > display->buf)
flushimage(display, 1); flushimage(display, 1);
switch(alt(a)){ switch(alt(a)){
case AMOUSE: case AMOUSE:
@ -630,19 +675,20 @@ waitio(void)
selection(); selection();
else if(button2() || button3()) else if(button2() || button3())
readmenu(); readmenu();
else if(resize_flag == 0)
goto Next;
break; break;
case ARESIZE: case ARESIZE:
resize_flag = 2; resize_flag = 2;
break; break;
case AHOST: case AHOST:
hostbufp = hostbuf; hostbufp = hostbuf;
if(hostbufp == nil){ if(hostbuf == nil){
close(hostfd); close(hostfd);
hostfd = -1; hostfd = -1;
} }
break; break;
} }
cursoff(); /* turn cursor back off */
} }
void void
@ -681,9 +727,14 @@ resize(void)
yscrmax = ymax; yscrmax = ymax;
olines = 0; olines = 0;
exportsize(); exportsize();
free(onscreen);
onscreen = mallocz((ymax+1)*(xmax+2)*sizeof(Rune), 1); free(onscreenrbuf);
border(screen, screen->r, XMARGIN+YMARGIN, bgcolor, ZP); onscreenrbuf = mallocz((ymax+1)*(xmax+2)*sizeof(Rune), 1);
free(onscreenabuf);
onscreenabuf = mallocz((ymax+1)*(xmax+2), 1);
free(onscreencbuf);
onscreencbuf = mallocz((ymax+1)*(xmax+2), 1);
clear(0,0,xmax+1,ymax+1); clear(0,0,xmax+1,ymax+1);
if(resize_flag > 1) if(resize_flag > 1)
backup(backc); backup(backc);
@ -694,21 +745,19 @@ resize(void)
void void
setdim(int ht, int wid) setdim(int ht, int wid)
{ {
int fd;
Rectangle r; Rectangle r;
int fd;
if(ht != -1) if(wid <= 0) wid = xmax+1;
ymax = ht-1; if(ht <= 0) ht = ymax+1;
if(wid != -1)
xmax = wid-1;
r.min = screen->r.min; r.min = screen->r.min;
r.max = addpt(screen->r.min, Pt((xmax+1)*CW+2*INSET, (ymax+1)*NS+2*INSET)); r.max = addpt(screen->r.min, Pt(wid*CW+2*INSET, ht*NS+2*INSET));
fd = open("/dev/wctl", OWRITE); fd = open("/dev/wctl", OWRITE);
if(fd < 0 || fprint(fd, "resize -dx %d -dy %d\n", Dx(r)+2*Borderwidth, Dy(r)+2*Borderwidth) < 0) if(fd >= 0){
resize(); fprint(fd, "resize -dx %d -dy %d\n", Dx(r)+2*Borderwidth, Dy(r)+2*Borderwidth);
if(fd >= 0)
close(fd); close(fd);
} }
}
void void
sendsnarf(void) sendsnarf(void)
@ -769,10 +818,10 @@ selection(void)
backup = allocimage(display, screen->r, screen->chan, 0, DNofill); backup = allocimage(display, screen->r, screen->chan, 0, DNofill);
draw(backup, backup->r, screen, nil, backup->r.min); draw(backup, backup->r, screen, nil, backup->r.min);
p = pos(mouse.xy); p = pos(mc->xy);
do { do {
q = pos(mouse.xy); q = pos(mc->xy);
if(onscreenp(p.x, p.y) > onscreenp(q.x, q.y)){ if(onscreenr(p.x, p.y) > onscreenr(q.x, q.y)){
r.min = q; r.min = q;
r.max = p; r.max = p;
} else { } else {
@ -784,12 +833,11 @@ selection(void)
d = drawselection(r, ZR, red); d = drawselection(r, ZR, red);
flushimage(display, 1); flushimage(display, 1);
readmouse(mc); readmouse(mc);
mouse = mc->Mouse;
draw(screen, d, backup, nil, d.min); draw(screen, d, backup, nil, d.min);
} while(button1()); } while(button1());
if((mouse.buttons & 07) == 5) if((mc->buttons & 07) == 5)
sendsnarf(); sendsnarf();
else if(writesnarf(onscreenp(r.min.x, r.min.y), onscreenp(r.max.x, r.max.y))){ else if(writesnarf(onscreenr(r.min.x, r.min.y), onscreenr(r.max.x, r.max.y))){
d = drawselection(r, ZR, green); d = drawselection(r, ZR, green);
flushimage(display, 1); flushimage(display, 1);
sleep(200); sleep(200);
@ -924,17 +972,12 @@ pos(Point pt)
return pt; return pt;
} }
Rune*
onscreenp(int x, int y)
{
return onscreen + (y*(xmax+2) + x);
}
void void
scroll(int sy, int ly, int dy, int cy) /* source, limit, dest, which line to clear */ scroll(int sy, int ly, int dy, int cy) /* source, limit, dest, which line to clear */
{ {
memmove(onscreenp(0, dy), onscreenp(0, sy), (ly-sy)*(xmax+2)*sizeof(Rune)); memmove(onscreenr(0, dy), onscreenr(0, sy), (ly-sy)*(xmax+2)*sizeof(Rune));
draw(screen, Rpt(pt(0, dy), pt(xmax+1, dy+ly-sy)), screen, nil, pt(0, sy)); memmove(onscreena(0, dy), onscreena(0, sy), (ly-sy)*(xmax+2));
memmove(onscreenc(0, dy), onscreenc(0, sy), (ly-sy)*(xmax+2));
clear(0, cy, xmax+1, cy+1); clear(0, cy, xmax+1, cy+1);
} }
@ -950,8 +993,9 @@ bigscroll(void) /* scroll up half a page */
x = y = 0; x = y = 0;
return; return;
} }
draw(screen, Rpt(pt(0, 0), pt(xmax+1, ymax+1)), screen, nil, pt(0, half)); memmove(onscreenr(0, 0), onscreenr(0, half), (ymax-half+1)*(xmax+2)*sizeof(Rune));
memmove(onscreenp(0, 0), onscreenp(0, half), (ymax-half+1)*(xmax+2)*sizeof(Rune)); memmove(onscreena(0, 0), onscreena(0, half), (ymax-half+1)*(xmax+2));
memmove(onscreenc(0, 0), onscreenc(0, half), (ymax-half+1)*(xmax+2));
clear(0, y-half+1, xmax+1, ymax+1); clear(0, y-half+1, xmax+1, ymax+1);
y -= half; y -= half;
if(olines) if(olines)
@ -992,7 +1036,9 @@ host_avail(void)
{ {
if(*echop != 0 && fullrune(echop, strlen(echop))) if(*echop != 0 && fullrune(echop, strlen(echop)))
return 1; return 1;
return hostbufp != nil && *hostbufp != 0; if(hostbuf == nil)
return 0;
return *hostbufp != 0;
} }
int int
@ -1051,28 +1097,10 @@ funckey(int key)
sendnchars(strlen(fk[key].sequence), fk[key].sequence); sendnchars(strlen(fk[key].sequence), fk[key].sequence);
} }
void void
drawstring(Rune *str, int n, int attr) drawstring(Rune *str, int n)
{ {
int i; memmove(onscreenr(x, y), str, n*sizeof(Rune));
Image *txt, *bg, *tmp; memset(onscreena(x, y), attr & 0xFF, n);
Point p; memset(onscreenc(x, y), attr >> 8, n);
txt = fgcolor;
bg = bgcolor;
if(attr & TReverse){
tmp = txt;
txt = bg;
bg = tmp;
}
if(attr & THighIntensity){
for(i=0; i<8; i++)
if(txt == colors[i])
txt = hicolors[i];
}
p = pt(x, y);
draw(screen, Rpt(p, addpt(p, runestringsize(font, str))), bg, nil, p);
runestring(screen, p, txt, ZP, font, str);
memmove(onscreenp(x, y), str, n*sizeof(Rune));
} }

View file

@ -143,7 +143,6 @@ emulate(void)
int savex, savey, saveattr, saveisgraphics; int savex, savey, saveattr, saveisgraphics;
int isgraphics; int isgraphics;
int g0set, g1set; int g0set, g1set;
int dch;
isgraphics = 0; isgraphics = 0;
g0set = 'B'; /* US ASCII */ g0set = 'B'; /* US ASCII */
@ -237,7 +236,7 @@ emulate(void)
break; break;
case '\033': case '\033':
switch(dch = get_next_char()){ switch(get_next_char()){
/* /*
* 1 - graphic processor option on (no-op; not installed) * 1 - graphic processor option on (no-op; not installed)
*/ */
@ -254,7 +253,6 @@ emulate(void)
* 7 - save cursor position. * 7 - save cursor position.
*/ */
case '7': case '7':
//print("save\n");
savex = x; savex = x;
savey = y; savey = y;
saveattr = attr; saveattr = attr;
@ -265,7 +263,6 @@ emulate(void)
* 8 - restore cursor position. * 8 - restore cursor position.
*/ */
case '8': case '8':
//print("restore\n");
x = savex; x = savex;
y = savey; y = savey;
attr = saveattr; attr = saveattr;
@ -276,7 +273,6 @@ emulate(void)
* c - Reset terminal. * c - Reset terminal.
*/ */
case 'c': case 'c':
print("resetterminal\n");
cursoron = 1; cursoron = 1;
ttystate[cs->raw].nlcr = 0; ttystate[cs->raw].nlcr = 0;
break; break;
@ -401,7 +397,7 @@ print("resetterminal\n");
/* /*
* do escape2 stuff * do escape2 stuff
*/ */
switch(dch = buf[0]){ switch(buf[0]){
/* /*
* c - same as ESC Z: what are you? * c - same as ESC Z: what are you?
*/ */
@ -803,13 +799,6 @@ print("resetterminal\n");
break; break;
} }
break; break;
/*
* Anything else we ignore for now...
*/
default:
print("unknown escape2 '%c' (0x%x)\n", dch, dch);
break;
} }
break; break;
@ -825,14 +814,6 @@ print("unknown escape2 '%c' (0x%x)\n", dch, dch);
case ']': case ']':
osc(); osc();
break; break;
/*
* Ignore other commands.
*/
default:
print("unknown command '%c' (0x%x)\n", dch, dch);
break;
} }
break; break;
@ -858,7 +839,7 @@ Default:
c = 0; c = 0;
} }
buf[n] = 0; buf[n] = 0;
drawstring(buf, n, attr); drawstring(buf, n);
x += n; x += n;
peekc = c; peekc = c;
break; break;
@ -875,8 +856,6 @@ setattr(int argc, int *argv)
switch(argv[i]) { switch(argv[i]) {
case 0: case 0:
attr = defattr; attr = defattr;
fgcolor = fgdefault;
bgcolor = bgdefault;
break; break;
case 1: case 1:
attr |= THighIntensity; attr |= THighIntensity;
@ -916,10 +895,10 @@ setattr(int argc, int *argv)
case 35: /* purple */ case 35: /* purple */
case 36: /* cyan */ case 36: /* cyan */
case 37: /* white */ case 37: /* white */
fgcolor = (nocolor? fgdefault: colors[argv[i]-30]); attr = (attr & ~0xF000) | 0x1000 | (argv[i]-30)<<13;
break; break;
case 39: case 39: /* default */
fgcolor = fgdefault; attr &= ~0xF000;
break; break;
case 40: /* black */ case 40: /* black */
case 41: /* red */ case 41: /* red */
@ -929,10 +908,10 @@ setattr(int argc, int *argv)
case 45: /* purple */ case 45: /* purple */
case 46: /* cyan */ case 46: /* cyan */
case 47: /* white */ case 47: /* white */
bgcolor = (nocolor? bgdefault: colors[argv[i]-40]); attr = (attr & ~0x0F00) | 0x0100 | (argv[i]-40)<<9;
break; break;
case 49: case 49: /* default */
bgcolor = bgdefault; attr &= ~0x0F00;
break; break;
} }
} }
@ -965,9 +944,6 @@ osc(void)
close(fd); close(fd);
} }
break; break;
default:
fprint(2, "unknown osc escape %d\n", osc);
break;
} }
} }
} }