vt: implement snarf support
This commit is contained in:
parent
34f5a83330
commit
ddc6c16515
|
@ -8,9 +8,7 @@ struct Consstate{
|
|||
extern Consstate* consctl(void);
|
||||
extern Consstate* cs;
|
||||
|
||||
#define XMARGIN 5 /* inset from border of layer */
|
||||
#define YMARGIN 5
|
||||
#define INSET 3
|
||||
#define INSET 2
|
||||
#define BUFS 32
|
||||
#define HISTSIZ 4096 /* number of history characters */
|
||||
#define BSIZE 1000
|
||||
|
@ -30,8 +28,8 @@ enum {
|
|||
TReverse = (1<<3),
|
||||
TInvisible = (1<<4),
|
||||
};
|
||||
|
||||
|
||||
#define button1() ((mouse.buttons & 07)==1)
|
||||
#define button2() ((mouse.buttons & 07)==2)
|
||||
#define button3() ((mouse.buttons & 07)==4)
|
||||
|
||||
|
@ -55,7 +53,7 @@ extern char* term;
|
|||
|
||||
extern void emulate(void);
|
||||
extern int host_avail(void);
|
||||
extern void clear(Rectangle);
|
||||
extern void clear(int,int,int,int);
|
||||
extern void newline(void);
|
||||
extern int get_next_char(void);
|
||||
extern void ringbell(void);
|
||||
|
@ -64,8 +62,9 @@ extern void scroll(int,int,int,int);
|
|||
extern void backup(int);
|
||||
extern void sendnchars(int, char *);
|
||||
extern Point pt(int, int);
|
||||
extern Point pos(Point);
|
||||
extern void funckey(int);
|
||||
extern void drawstring(Point, Rune*, int);
|
||||
extern void drawstring(Rune*, int, int);
|
||||
|
||||
extern int debug;
|
||||
extern int yscrmin, yscrmax;
|
||||
|
|
|
@ -47,6 +47,7 @@ Menu menu2;
|
|||
Menu menu3;
|
||||
Rune *histp;
|
||||
Rune hist[HISTSIZ];
|
||||
Rune *onscreen;
|
||||
int yscrmin, yscrmax;
|
||||
int attr, defattr;
|
||||
int wctlout;
|
||||
|
@ -56,10 +57,12 @@ Image *cursback;
|
|||
Image *colors[8];
|
||||
Image *hicolors[8];
|
||||
Image *red;
|
||||
Image *green;
|
||||
Image *fgcolor;
|
||||
Image *bgcolor;
|
||||
Image *fgdefault;
|
||||
Image *bgdefault;
|
||||
Image *highlight;
|
||||
|
||||
uint rgbacolors[8] = {
|
||||
0x000000FF, /* black */
|
||||
|
@ -88,6 +91,8 @@ struct ttystate ttystate[2] = { {0, 1}, {0, 1} };
|
|||
|
||||
int NS;
|
||||
int CW;
|
||||
int XMARGIN;
|
||||
int YMARGIN;
|
||||
Consstate *cs;
|
||||
Mouse mouse;
|
||||
|
||||
|
@ -119,11 +124,13 @@ void set_input(char *);
|
|||
void set_host(Event *);
|
||||
void bigscroll(void);
|
||||
void readmenu(void);
|
||||
void selection(void);
|
||||
void eresized(int);
|
||||
void resize(void);
|
||||
void send_interrupt(void);
|
||||
int alnum(int);
|
||||
void escapedump(int,uchar *,int);
|
||||
Rune* onscreenp(int, int);
|
||||
|
||||
void
|
||||
main(int argc, char **argv)
|
||||
|
@ -210,8 +217,10 @@ initialize(int argc, char **argv)
|
|||
CW = stringwidth(font, "m");
|
||||
|
||||
red = allocimage(display, Rect(0,0,1,1), screen->chan, 1, DRed);
|
||||
green = allocimage(display, Rect(0,0,1,1), screen->chan, 1, DGreen);
|
||||
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);
|
||||
|
||||
for(i=0; i<8; i++){
|
||||
colors[i] = allocimage(display, Rect(0,0,1,1), screen->chan, 1,
|
||||
|
@ -234,14 +243,23 @@ initialize(int argc, char **argv)
|
|||
}
|
||||
|
||||
void
|
||||
clear(Rectangle r)
|
||||
clear(int x1, int y1, int x2, int y2)
|
||||
{
|
||||
draw(screen, r, bgcolor, nil, ZP);
|
||||
draw(screen, Rpt(pt(x1,y1), pt(x2,y2)), bgcolor, nil, ZP);
|
||||
while(y1 < y2){
|
||||
if(x1 < x2)
|
||||
memset(onscreenp(x1, y1), 0, (x2-x1)*sizeof(Rune));
|
||||
if(x2 > xmax)
|
||||
*onscreenp(xmax+1, y1) = '\n';
|
||||
y1++;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
newline(void)
|
||||
{
|
||||
if(x > xmax)
|
||||
*onscreenp(xmax+1, y) = 0; /* wrap arround, remove hidden newline */
|
||||
nbacklines--;
|
||||
if(y >= yscrmax) {
|
||||
y = yscrmax;
|
||||
|
@ -427,8 +445,12 @@ waitchar(void)
|
|||
wasblocked = blocked;
|
||||
if(backp)
|
||||
return(0);
|
||||
if(ecanmouse() && (button2() || button3()))
|
||||
readmenu();
|
||||
if(ecanmouse()){
|
||||
if(button1())
|
||||
selection();
|
||||
else if(button2() || button3())
|
||||
readmenu();
|
||||
}
|
||||
if(snarffp) {
|
||||
static Rune lastc = ~0;
|
||||
|
||||
|
@ -535,13 +557,16 @@ waitchar(void)
|
|||
continue;
|
||||
}
|
||||
curson(wasblocked); /* turn on cursor while we're waiting */
|
||||
flushimage(display, 1);
|
||||
do {
|
||||
newmouse = 0;
|
||||
switch(eread(blocked ? Emouse|Ekeyboard :
|
||||
Emouse|Ekeyboard|Ehost, &e)) {
|
||||
case Emouse:
|
||||
mouse = e.mouse;
|
||||
if(button2() || button3())
|
||||
if(button1())
|
||||
selection();
|
||||
else if(button2() || button3())
|
||||
readmenu();
|
||||
else if(resize_flag == 0) {
|
||||
/* eresized() is triggered by special mouse event */
|
||||
|
@ -581,8 +606,8 @@ putenvint(char *name, int x)
|
|||
void
|
||||
exportsize(void)
|
||||
{
|
||||
putenvint("XPIXELS", Dx(screen->r)-2*XMARGIN);
|
||||
putenvint("YPIXELS", Dy(screen->r)-2*XMARGIN);
|
||||
putenvint("XPIXELS", (xmax+1)*CW);
|
||||
putenvint("YPIXELS", (ymax+1)*NS);
|
||||
putenvint("LINES", ymax+1);
|
||||
putenvint("COLS", xmax+1);
|
||||
putenv("TERM", term);
|
||||
|
@ -595,17 +620,20 @@ resize(void)
|
|||
fprint(2, "can't reattach to window: %r\n");
|
||||
exits("can't reattach to window");
|
||||
}
|
||||
xmax = (Dx(screen->r)-2*XMARGIN)/CW-1;
|
||||
ymax = (Dy(screen->r)-2*YMARGIN)/NS-1;
|
||||
if(xmax == 0 || ymax == 0)
|
||||
exits("window gone");
|
||||
draw(screen, screen->r, bgcolor, nil, ZP);
|
||||
xmax = (Dx(screen->r) - 2*INSET)/CW-1;
|
||||
ymax = (Dy(screen->r) - 2*INSET)/NS-1;
|
||||
XMARGIN = (Dx(screen->r) - (xmax+1)*CW) / 2;
|
||||
YMARGIN = (Dy(screen->r) - (ymax+1)*NS) / 2;
|
||||
x = 0;
|
||||
y = 0;
|
||||
yscrmin = 0;
|
||||
yscrmax = ymax;
|
||||
free(onscreen);
|
||||
onscreen = mallocz((ymax+1)*(xmax+2)*sizeof(Rune), 1);
|
||||
olines = 0;
|
||||
exportsize();
|
||||
clear(screen->r);
|
||||
clear(0,0,xmax+1,ymax+1);
|
||||
if(resize_flag > 1)
|
||||
backup(backc);
|
||||
resize_flag = 0;
|
||||
|
@ -622,21 +650,102 @@ setdim(int ht, int wid)
|
|||
ymax = ht-1;
|
||||
if(wid != -1)
|
||||
xmax = wid-1;
|
||||
|
||||
r.min = screen->r.min;
|
||||
r.max = addpt(screen->r.min,
|
||||
Pt((xmax+1)*CW+2*XMARGIN+2*INSET,
|
||||
(ymax+1)*NS+2*YMARGIN+2*INSET));
|
||||
r.max = addpt(screen->r.min, Pt((xmax+1)*CW+2*INSET, (ymax+1)*NS+2*INSET));
|
||||
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){
|
||||
border(screen, r, INSET, bordercol, ZP);
|
||||
exportsize();
|
||||
}
|
||||
if(fd < 0 || fprint(fd, "resize -dx %d -dy %d\n", Dx(r)+2*Borderwidth, Dy(r)+2*Borderwidth) < 0)
|
||||
resize();
|
||||
if(fd >= 0)
|
||||
close(fd);
|
||||
}
|
||||
|
||||
void
|
||||
sendsnarf(void)
|
||||
{
|
||||
if(snarffp == nil)
|
||||
snarffp = Bopen("/dev/snarf",OREAD);
|
||||
}
|
||||
|
||||
int
|
||||
writesnarf(Rune *s, Rune *e)
|
||||
{
|
||||
Biobuf *b;
|
||||
int z, p;
|
||||
|
||||
if(s >= e)
|
||||
return 0;
|
||||
b = Bopen("/dev/snarf", OWRITE|OTRUNC);
|
||||
if(b == nil)
|
||||
return 0;
|
||||
for(z = p = 0; s < e; s++){
|
||||
if(*s){
|
||||
if(*s == '\n')
|
||||
z = p = 0;
|
||||
else if(p++ == 0){
|
||||
while(z-- > 0) Bputc(b, ' ');
|
||||
}
|
||||
Bputrune(b, *s);
|
||||
} else {
|
||||
z++;
|
||||
}
|
||||
}
|
||||
Bterm(b);
|
||||
return 1;
|
||||
}
|
||||
|
||||
Rectangle
|
||||
drawselection(Rectangle r, Rectangle d, Image *color)
|
||||
{
|
||||
while(r.min.y < r.max.y){
|
||||
d = drawselection(Rect(r.min.x, r.min.y, xmax+1, r.min.y), d, color);
|
||||
r.min.x = 0;
|
||||
r.min.y++;
|
||||
}
|
||||
if(r.min.x >= r.max.x)
|
||||
return d;
|
||||
r = Rpt(pt(r.min.x, r.min.y), pt(r.max.x, r.max.y+1));
|
||||
draw(screen, r, color, highlight, r.min);
|
||||
combinerect(&d, r);
|
||||
return d;
|
||||
}
|
||||
|
||||
void
|
||||
selection(void)
|
||||
{
|
||||
Point p, q;
|
||||
Rectangle r, d;
|
||||
Image *backup;
|
||||
|
||||
backup = allocimage(display, screen->r, screen->chan, 0, DNofill);
|
||||
draw(backup, backup->r, screen, nil, backup->r.min);
|
||||
p = pos(mouse.xy);
|
||||
do {
|
||||
q = pos(mouse.xy);
|
||||
if(onscreenp(p.x, p.y) > onscreenp(q.x, q.y)){
|
||||
r.min = q;
|
||||
r.max = p;
|
||||
} else {
|
||||
r.min = p;
|
||||
r.max = q;
|
||||
}
|
||||
if(r.max.y > ymax)
|
||||
r.max.x = 0;
|
||||
d = drawselection(r, ZR, red);
|
||||
flushimage(display, 1);
|
||||
mouse = emouse();
|
||||
draw(screen, d, backup, nil, d.min);
|
||||
} while(button1());
|
||||
if((mouse.buttons & 07) == 5)
|
||||
sendsnarf();
|
||||
else if(writesnarf(onscreenp(r.min.x, r.min.y), onscreenp(r.max.x, r.max.y))){
|
||||
d = drawselection(r, ZR, green);
|
||||
flushimage(display, 1);
|
||||
sleep(200);
|
||||
draw(screen, d, backup, nil, d.min);
|
||||
}
|
||||
freeimage(backup);
|
||||
}
|
||||
|
||||
void
|
||||
readmenu(void)
|
||||
{
|
||||
|
@ -693,7 +802,7 @@ readmenu(void)
|
|||
return;
|
||||
|
||||
case 4: /* send the snarf buffer */
|
||||
snarffp = Bopen("/dev/snarf",OREAD);
|
||||
sendsnarf();
|
||||
return;
|
||||
|
||||
case 5: /* pause and clear at end of screen */
|
||||
|
@ -745,12 +854,36 @@ pt(int x, int y)
|
|||
return addpt(screen->r.min, Pt(x*CW+XMARGIN,y*NS+YMARGIN));
|
||||
}
|
||||
|
||||
Point
|
||||
pos(Point pt)
|
||||
{
|
||||
pt.x -= screen->r.min.x + XMARGIN;
|
||||
pt.y -= screen->r.min.y + YMARGIN;
|
||||
pt.x /= CW;
|
||||
pt.y /= NS;
|
||||
if(pt.x < 0)
|
||||
pt.x = 0;
|
||||
else if(pt.x > xmax+1)
|
||||
pt.x = xmax+1;
|
||||
if(pt.y < 0)
|
||||
pt.y = 0;
|
||||
else if(pt.y > ymax+1)
|
||||
pt.y = ymax+1;
|
||||
return pt;
|
||||
}
|
||||
|
||||
Rune*
|
||||
onscreenp(int x, int y)
|
||||
{
|
||||
return onscreen + (y*(xmax+2) + x);
|
||||
}
|
||||
|
||||
void
|
||||
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));
|
||||
draw(screen, Rpt(pt(0, dy), pt(xmax+1, dy+ly-sy)), screen, nil, pt(0, sy));
|
||||
clear(Rpt(pt(0, cy), pt(xmax+1, cy+1)));
|
||||
flushimage(display, 1);
|
||||
clear(0, cy, xmax+1, cy+1);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -761,16 +894,16 @@ bigscroll(void) /* scroll up half a page */
|
|||
if(x == 0 && y == 0)
|
||||
return;
|
||||
if(y < half) {
|
||||
clear(Rpt(pt(0,0),pt(xmax+1,ymax+1)));
|
||||
clear(0, 0, xmax+1, ymax+1);
|
||||
x = y = 0;
|
||||
return;
|
||||
}
|
||||
draw(screen, Rpt(pt(0, 0), pt(xmax+1, ymax+1)), screen, nil, pt(0, half));
|
||||
clear(Rpt(pt(0,y-half+1),pt(xmax+1,ymax+1)));
|
||||
memmove(onscreenp(0, 0), onscreenp(0, half), (ymax-half+1)*(xmax+2)*sizeof(Rune));
|
||||
clear(0, y-half+1, xmax+1, ymax+1);
|
||||
y -= half;
|
||||
if(olines)
|
||||
olines -= half;
|
||||
flushimage(display, 1);
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -888,11 +1021,12 @@ funckey(int key)
|
|||
|
||||
|
||||
void
|
||||
drawstring(Point p, Rune *str, int attr)
|
||||
drawstring(Rune *str, int n, int attr)
|
||||
{
|
||||
int i;
|
||||
Image *txt, *bg, *tmp;
|
||||
|
||||
Point p;
|
||||
|
||||
txt = fgcolor;
|
||||
bg = bgcolor;
|
||||
if(attr & TReverse){
|
||||
|
@ -905,7 +1039,8 @@ drawstring(Point p, Rune *str, int attr)
|
|||
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));
|
||||
}
|
||||
|
|
|
@ -687,21 +687,21 @@ print("resetterminal\n");
|
|||
* operand 2: whole screen.
|
||||
*/
|
||||
case 2:
|
||||
clear(Rpt(pt(0, 0), pt(xmax+1, ymax+1)));
|
||||
clear(0, 0, xmax+1, ymax+1);
|
||||
break;
|
||||
/*
|
||||
* operand 1: start of screen to active position, inclusive.
|
||||
*/
|
||||
case 1:
|
||||
clear(Rpt(pt(0, 0), pt(xmax+1, y)));
|
||||
clear(Rpt(pt(0, y), pt(x+1, y+1)));
|
||||
clear(0, 0, xmax+1, y);
|
||||
clear(0, y, x+1, y+1);
|
||||
break;
|
||||
/*
|
||||
* Default: active position to end of screen, inclusive.
|
||||
*/
|
||||
default:
|
||||
clear(Rpt(pt(x, y), pt(xmax+1, y+1)));
|
||||
clear(Rpt(pt(0, y+1), pt(xmax+1, ymax+1)));
|
||||
clear(x, y, xmax+1, y+1);
|
||||
clear(0, y+1, xmax+1, ymax+1);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
@ -715,19 +715,19 @@ print("resetterminal\n");
|
|||
* operand 2: whole line.
|
||||
*/
|
||||
case 2:
|
||||
clear(Rpt(pt(0, y), pt(xmax+1, y+1)));
|
||||
clear(0, y, xmax+1, y+1);
|
||||
break;
|
||||
/*
|
||||
* operand 1: start of line to active position, inclusive.
|
||||
*/
|
||||
case 1:
|
||||
clear(Rpt(pt(0, y), pt(x+1, y+1)));
|
||||
clear(0, y, x+1, y+1);
|
||||
break;
|
||||
/*
|
||||
* Default: active position to end of line, inclusive.
|
||||
*/
|
||||
default:
|
||||
clear(Rpt(pt(x, y), pt(xmax+1, y+1)));
|
||||
clear(x, y, xmax+1, y+1);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
@ -739,7 +739,7 @@ print("resetterminal\n");
|
|||
fixops(operand);
|
||||
i = x + operand[0];
|
||||
draw(screen, Rpt(pt(x, y), pt(xmax+1, y+1)), screen, nil, pt(i, y));
|
||||
clear(Rpt(pt(xmax-operand[0], y), pt(xmax+1, y+1)));
|
||||
clear(xmax-operand[0], y, xmax+1, y+1);
|
||||
break;
|
||||
|
||||
/*
|
||||
|
@ -749,7 +749,7 @@ print("resetterminal\n");
|
|||
fixops(operand);
|
||||
i = x + operand[0];
|
||||
draw(screen, Rpt(pt(i, y), pt(xmax+1, y+1)), screen, nil, pt(x, y));
|
||||
clear(Rpt(pt(x, y), pt(i, y+1)));
|
||||
clear(x, y, i, y+1);
|
||||
break;
|
||||
|
||||
|
||||
|
@ -759,7 +759,7 @@ print("resetterminal\n");
|
|||
case 'X':
|
||||
fixops(operand);
|
||||
i = x + operand[0];
|
||||
clear(Rpt(pt(x, y), pt(i, y+1)));
|
||||
clear(x, y, i, y+1);
|
||||
break;
|
||||
|
||||
/*
|
||||
|
@ -844,8 +844,8 @@ Default:
|
|||
/* line wrap */
|
||||
if (x > xmax){
|
||||
if(wraparound){
|
||||
x = 0;
|
||||
newline();
|
||||
x = 0;
|
||||
}else{
|
||||
continue;
|
||||
}
|
||||
|
@ -858,7 +858,7 @@ Default:
|
|||
c = 0;
|
||||
}
|
||||
buf[n] = 0;
|
||||
drawstring(pt(x, y), buf, attr);
|
||||
drawstring(buf, n, attr);
|
||||
x += n;
|
||||
peekc = c;
|
||||
break;
|
||||
|
|
Loading…
Reference in a new issue