* Re: [9fans] The VT saga
2000-09-11 9:41 lucio
@ 2000-11-07 14:32 ` Micah Stetson
0 siblings, 0 replies; 9+ messages in thread
From: Micah Stetson @ 2000-11-07 14:32 UTC (permalink / raw)
To: 9fans
[-- Attachment #1: Type: text/plain, Size: 1228 bytes --]
I took a look at vt tonight and while vttest still just turns
up its nose at me, it looks like I've eliminated most of the
real problems I had with Mutt and vi. There are mainly
three changes.
First, I finally think I've got scroll() right. Lucio's
previous patch said
> /mnt/wrap/sys/src/cmd/vt/main.c:577 c /sys/src/cmd/vt/main.c:584
> < draw(screen, Rpt(pt(0, dy), pt(xmax+1, ly-sy)), screen, nil, pt(0, sy));
> ---
> > draw(screen, Rpt(pt(0, dy), pt(xmax+1, ly+1)), screen, nil, pt(0, sy));
but it should really have dy+ly-sy in there.
Second, I made the delete to end of line and delete to end of
screen stuff work like the vt100 user's guide says it should.
Last, I changed yscrmin and yscrmax so that they are always the
beginning and end of the scrolling region even when that region
is the whole screen. That got rid of a bunch of lines that
looked like
M = yscrmax ? yscrmax : ymax;
Maybe there was a good reason for doing it the other way, but
I don't see it.
Anyway, attached are my current in-progress versions of vt.c
and main.c from /sys/src/cmd/vt. They do not include the
patch Lucio posted to this list a few weeks back. I hope
this is helpful to somebody.
Micah
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: main.c --]
[-- Type: text/x-csrc, Size: 12856 bytes --]
#include <u.h>
#include <libc.h>
#include <draw.h>
#include <event.h>
#include <bio.h>
#include <keyboard.h>
#include "cons.h"
enum{
Ehost = 4,
};
char *menutext2[] = {
"backup",
"forward",
"reset",
"clear",
"send",
"page",
0
};
char *menutext3[] = {
"24x80",
"crnl",
"nl",
"raw",
0
};
/* variables associated with the screen */
int x, y; /* character positions */
char *backp;
int backc;
int atend;
int nbacklines;
int xmax, ymax;
int blocked;
int resize_flag;
int pagemode;
int olines;
int peekc;
Menu menu2;
Menu menu3;
char *histp;
char hist[HISTSIZ];
int yscrmin, yscrmax;
Image *text;
Image *background;
Image *bordercol;
Image *cursback;
Image *red;
/* terminal control */
struct ttystate ttystate[2] = { {0, 1}, {0,0} };
int NS;
int CW;
Consstate *cs;
Mouse mouse;
int outfd = -1;
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];
char *echop = echo_input; /* characters to echo, after canon */
char sendbuf[BSIZE]; /* hope you can't type ahead more than BSIZE chars */
char *sendp = sendbuf;
/* functions */
void initialize(int, char **);
void ebegin(int);
int waitchar(void);
int rcvchar(void);
void set_input(char *);
void set_host(Event *);
void bigscroll(void);
void readmenu(void);
void eresized(int);
void resize(void);
void send_interrupt(void);
int alnum(int);
void escapedump(int,uchar *,int);
char *term;
struct funckey *fk;
int debug;
void
main(int argc, char **argv)
{
initialize(argc, argv);
emulate();
}
void
initialize(int argc, char **argv)
{
int dayglo = 1;
rfork(RFENVG|RFNAMEG|RFNOTEG);
term = "vt100";
fk = vt100fk;
ARGBEGIN{
case '2':
term = "vt220";
fk = vt220fk;
break;
case 's': /* for sape */
dayglo = 0;
break;
}ARGEND;
host_buf = malloc(host_bsize);
hostp = host_buf;
hostlength = 0;
if(initdraw(0,0,term) < 0){
fprint(2, "%s: initdraw failed: %r\n", term);
exits("initdraw");
}
ebegin(Ehost);
histp = hist;
menu2.item = menutext2;
menu3.item = menutext3;
pagemode = 0;
blocked = 0;
NS = font->height ;
CW = stringwidth(font, "m");
text = allocimage(display, Rect(0,0,1,1), screen->chan, 1, dayglo?0x00F0F0F0:0);
background = allocimage(display, Rect(0,0,1,1), screen->chan, 1, dayglo?0x33333333:-1);
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);
red = allocimage(display, Rect(0, 0, CW+1, NS+1), screen->chan, 1, DRed);
eresized(0);
if(argc > 0) {
sendnchars(strlen(argv[0]),argv[0]);
sendnchars(1,"\n");
}
}
void
clear(Rectangle r)
{
draw(screen, r, background, nil, ZP);
}
void
newline(void)
{
nbacklines--;
if(y >= yscrmax) {
y = yscrmax;
if(pagemode && olines >= yscrmax) {
blocked = 1;
return;
}
scroll(yscrmin+1, yscrmax+1, yscrmin, yscrmax);
} else
y++;
olines++;
}
void
curson(int bl)
{
Image *col;
draw(cursback, cursback->r, screen, nil, subpt(pt(x, y),Pt(1,1)));
if(bl)
col = red;
else
col = bordercol;
border(screen, Rpt(subpt(pt(x, y), Pt(1, 1)), addpt(pt(x, y), Pt(CW,NS))),
2, col, ZP);
}
void
cursoff(void)
{
draw(screen, Rpt(subpt(pt(x, y), Pt(1, 1)), addpt(pt(x, y), Pt(CW,NS))),
cursback, nil, cursback->r.min);
}
int
get_next_char(void)
{
int c = peekc;
peekc = 0;
if(c > 0)
return(c);
while(c <= 0) {
if(backp) {
c = *backp;
if(c && nbacklines >= 0) {
backp++;
if(backp >= &hist[HISTSIZ])
backp = hist;
return(c);
}
backp = 0;
}
c = waitchar();
}
*histp++ = c;
if(histp >= &hist[HISTSIZ])
histp = hist;
*histp = '\0';
return(c);
}
int
canon(char *ep, int c)
{
if(c&0200)
return(SCROLL);
switch(c) {
case '\b':
if(sendp > sendbuf)
sendp--;
*ep++ = '\b';
*ep++ = ' ';
*ep++ = '\b';
break;
case 0x15: /* ^U line kill */
sendp = sendbuf;
*ep++ = '^';
*ep++ = 'U';
*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);
}
/* fall through */
default:
if(sendp < &sendbuf[512])
*sendp++ = c;
*ep++ = c;
break;
}
*ep = 0;
return(OTHER);
}
void
sendfk(char *name)
{
int i;
static int fd;
for(i=0; fk[i].name; i++)
if(strcmp(name, fk[i].name)==0){
sendnchars2(strlen(fk[i].sequence), fk[i].sequence);
return;
}
}
int
waitchar(void)
{
Event e;
int c;
char c2;
int newmouse;
int wasblocked;
int kbdchar = -1;
char echobuf[3*BSIZE];
static int lastc = -1;
for(;;) {
if(resize_flag)
resize();
wasblocked = blocked;
if(backp)
return(0);
if(ecanmouse() && (button2() || button3()))
readmenu();
if(snarffp) {
if((c = Bgetc(snarffp)) < 0) {
if(lastc != '\n')
write(outfd,"\n",1);
Bterm(snarffp);
snarffp = 0;
if(lastc != '\n') {
lastc = -1;
return('\n');
}
lastc = -1;
continue;
}
lastc = c;
c2 = c;
write(outfd, &c2, 1);
return(c);
}
if(!blocked && host_avail())
return(rcvchar());
if(kbdchar > 0) {
if(blocked)
resize();
if(cs->raw) {
switch(kbdchar){
case Kup:
sendfk("up key");
break;
case Kdown:
sendfk("down key");
break;
case Kleft:
sendfk("left key");
break;
case Kright:
sendfk("right key");
break;
default:
echobuf[0] = kbdchar;
sendnchars(1, echobuf);
break;
}
} else if(canon(echobuf,kbdchar) == SCROLL) {
if(!blocked)
bigscroll();
} else
strcat(echo_input,echobuf);
blocked = 0;
kbdchar = -1;
continue;
}
curson(wasblocked); /* turn on cursor while we're waiting */
do {
newmouse = 0;
switch(eread(blocked ? Emouse|Ekeyboard :
Emouse|Ekeyboard|Ehost, &e)) {
case Emouse:
mouse = e.mouse;
if(button2() || button3())
readmenu();
else if(resize_flag == 0) {
/* eresized() is triggered by special mouse event */
newmouse = 1;
}
break;
case Ekeyboard:
kbdchar = e.kbdc;
break;
case Ehost:
set_host(&e);
break;
default:
perror("protocol violation");
exits("protocol violation");
}
} while(newmouse == 1);
cursoff(); /* turn cursor back off */
}
return 1; /* to shut up compiler */
}
void
eresized(int new)
{
resize_flag = 1+new;
}
void
exportsize(void)
{
int fd;
char buf[10];
if((fd = create("/env/LINES", OWRITE, 0644)) > 0) {
sprint(buf,"%d",ymax+1);
write(fd,buf,strlen(buf));
close(fd);
}
if((fd = create("/env/COLS", OWRITE, 0644)) > 0) {
sprint(buf,"%d",xmax+1);
write(fd,buf,strlen(buf));
close(fd);
}
if((fd = create("/env/TERM", OWRITE, 0644)) > 0) {
fprint(fd, "%s", term);
close(fd);
}
}
void
resize(void)
{
if(resize_flag > 1 && getwindow(display, Refnone) < 0){
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");
x = 0;
y = 0;
yscrmin = 0;
yscrmax = ymax;
olines = 0;
exportsize();
clear(screen->r);
resize_flag = 0;
}
void
readmenu(void)
{
Rectangle r;
int fd;
if(button3()) {
menu3.item[1] = ttystate[cs->raw].crnl ? "cr" : "crnl";
menu3.item[2] = ttystate[cs->raw].nlcr ? "nl" : "nlcr";
menu3.item[3] = cs->raw ? "cooked" : "raw";
switch(emenuhit(3, &mouse, &menu3)) {
case 0: /* 24x80 */
r.min = screen->r.min;
r.max = addpt(screen->r.min,
Pt(80*CW+2*XMARGIN+2*INSET,
24*NS+2*YMARGIN+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);
xmax = 79;
ymax = 23;
exportsize();
}
if(fd >= 0)
close(fd);
return;
case 1: /* newline after cr? */
ttystate[cs->raw].crnl = !ttystate[cs->raw].crnl;
return;
case 2: /* cr after newline? */
ttystate[cs->raw].nlcr = !ttystate[cs->raw].nlcr;
return;
case 3: /* switch raw mode */
cs->raw = !cs->raw;
return;
}
return;
}
menu2.item[5] = pagemode? "scroll": "page";
switch(emenuhit(2, &mouse, &menu2)) {
case 0: /* back up */
if(atend == 0) {
backc++;
backup(backc);
}
return;
case 1: /* move forward */
backc--;
if(backc >= 0)
backup(backc);
else
backc = 0;
return;
case 2: /* reset */
backc = 0;
backup(0);
return;
case 3: /* clear screen */
eresized(0);
return;
case 4: /* send the snarf buffer */
snarffp = Bopen("/dev/snarf",OREAD);
return;
case 5: /* pause and clear at end of screen */
pagemode = 1-pagemode;
if(blocked && !pagemode) {
eresized(0);
blocked = 0;
}
return;
}
}
void
backup(int count)
{
register n;
register char *cp;
eresized(0);
n = 3*(count+1)*ymax/4;
cp = histp;
atend = 0;
while (n >= 0) {
cp--;
if(cp < hist)
cp = &hist[HISTSIZ-1];
if(*cp == '\0') {
atend = 1;
break;
}
if(*cp == '\n')
n--;
}
cp++;
if(cp >= &hist[HISTSIZ])
cp = hist;
backp = cp;
nbacklines = ymax-2;
}
Point
pt(int x, int y)
{
return addpt(screen->r.min, Pt(x*CW+XMARGIN,y*NS+YMARGIN));
}
void
scroll(int sy, int ly, int dy, int cy) /* source, limit, dest, which line to clear */
{
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)));
}
void
bigscroll(void) /* scroll up half a page */
{
int half = ymax/3;
if(x == 0 && y == 0)
return;
if(y < half) {
clear(Rpt(pt(0,0),pt(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)));
y -= half;
if(olines)
olines -= half;
}
int
number(char *p)
{
int c, n = 0;
while ((c = get_next_char()) >= '0' && c <= '9')
n = n*10 + c - '0';
*p = c;
return(n);
}
/* stubs */
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);
close(1);
close(2);
exits("write");
}
}
int
host_avail(void)
{
return(*echop || ((hostp - host_buf) < hostlength));
}
int
rcvchar(void)
{
int c;
if(*echop) {
c = *echop++;
if(!*echop) {
echop = echo_input;
*echop = 0;
}
return c;
}
return *hostp++;
}
void
set_host(Event *e)
{
hostlength = e->n;
if(hostlength > host_bsize) {
host_bsize *= 2;
host_buf = realloc(host_buf,host_bsize);
}
hostp = host_buf;
memmove(host_buf,e->data,hostlength);
host_buf[hostlength]=0;
}
void
ringbell(void){
}
int
alnum(int c)
{
if(c >= 'a' && c <= 'z')
return 1;
if(c >= 'A' && c <= 'Z')
return 1;
if(c >= '0' && c <= '9')
return 1;
return 0;
}
void
escapedump(int fd,uchar *str,int len)
{
int i;
for(i = 0; i < len; i++) {
if((str[i] < ' ' || str[i] > '\177') &&
str[i] != '\n' && str[i] != '\t') fprint(fd,"^%c",str[i]+64);
else if(str[i] == '\177') fprint(fd,"^$");
else if(str[i] == '\n') fprint(fd,"^J\n");
else fprint(fd,"%c",str[i]);
}
}
void
funckey(int key)
{
if(key >= NKEYS)
return;
if(fk[key].name == 0)
return;
sendnchars2(strlen(fk[key].sequence), fk[key].sequence);
}
void
drawstring(Point p, char *str, int standout)
{
Image *txt, *bg;
txt = text;
bg = background;
if(standout){
txt = background;
bg = text;
}
draw(screen, Rpt(p, addpt(p, stringsize(font, str))), bg, nil, p);
string(screen, p, txt, ZP, font, str);
}
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #3: vt.c --]
[-- Type: text/x-csrc, Size: 9949 bytes --]
#include <u.h>
#include <libc.h>
#include <draw.h>
#include <bio.h>
#include <ctype.h>
#include "cons.h"
struct funckey vt100fk[NKEYS] = {
{ "up key", "\033OA", },
{ "down key", "\033OB", },
{ "left key", "\033OD", },
{ "right key", "\033OC", },
};
struct funckey vt220fk[NKEYS] = {
{ "up key", "\033[A", },
{ "down key", "\033[B", },
{ "left key", "\033[D", },
{ "right key", "\033[C", },
};
char gmap[256] = {
['_'] ' ', /* blank */
['\\'] '*', /* diamond */
['a'] 'X', /* checkerboard */
['b'] '\t', /* HT */
['c'] '\x0C', /* FF */
['d'] '\r', /* CR */
['e'] '\n', /* LF */
['f'] 'o', /* degree */
['g'] '+', /* plus/minus */
['h'] '\n', /* NL, but close enough */
['i'] '\v', /* VT */
['j'] '+', /* lower right corner */
['k'] '+', /* upper right corner */
['l'] '+', /* upper left corner */
['m'] '+', /* lower left corner */
['n'] '+', /* crossing lines */
['o'] '-', /* horiz line - scan 1 */
['p'] '-', /* horiz line - scan 3 */
['q'] '-', /* horiz line - scan 5 */
['r'] '-', /* horiz line - scan 7 */
['s'] '-', /* horiz line - scan 9 */
['t'] '+', /* |- */
['u'] '+', /* -| */
['v'] '+', /* upside down T */
['w'] '+', /* rightside up T */
['x'] '|', /* vertical bar */
['y'] '<', /* less/equal */
['z'] '>', /* gtr/equal */
['{'] 'p', /* pi */
['|'] '!', /* not equal */
['}'] 'L', /* pound symbol */
['~'] '.', /* centered dot: · */
};
void
emulate(void)
{
char buf[BUFS+1];
int n;
int c;
int standout;
int operand, prevOperand;
int savex, savey;
int isgraphics;
int g0set, g1set;
standout = 0;
isgraphics = 0;
g0set = 'B'; /* US ASCII */
g1set = 'B'; /* US ASCII */
savex = savey = 0;
yscrmin = 0;
yscrmax = ymax;
for (;;) {
if (y > ymax) {
x = 0;
newline();
}
buf[0] = get_next_char();
buf[1] = '\0';
switch(buf[0]) {
case '\000':
case '\001':
case '\002':
case '\003':
case '\004':
case '\005':
case '\006':
break;
case '\007': /* bell */
ringbell();
break;
case '\010': /* backspace */
if (x > 0)
--x;
break;
case '\011': /* tab modulo 8 */
x = (x|7)+1;
break;
case '\012': /* linefeed */
case '\013':
case '\014':
newline();
standout = 0;
if (ttystate[cs->raw].nlcr)
x = 0;
break;
case '\015': /* carriage return */
x = 0;
standout = 0;
if (ttystate[cs->raw].crnl)
newline();
break;
case '\016': /* SO: invoke G1 char set */
isgraphics = (isdigit(g1set));
break;
case '\017': /* SI: invoke G0 char set */
isgraphics = (isdigit(g0set));
break;
case '\020': /* DLE */
case '\021': /* DC1 */
case '\022': /* XON */
case '\023': /* DC3 */
case '\024': /* XOFF */
case '\025': /* NAK */
case '\026': /* SYN */
case '\027': /* ETB */
case '\030': /* CAN: cancel escape sequence */
case '\031': /* EM: cancel escape sequence, display checkerboard */
case '\032': /* SUB: same as CAN */
break;
/* ESC, \033, is handled below */
case '\034': /* FS */
case '\035': /* GS */
case '\036': /* RS */
case '\037': /* US */
break;
case '\177': /* delete: ignored */
break;
case '\033':
switch(get_next_char()){
/*
* 7 - save cursor position.
*/
case '7':
savex = x;
savey = y;
break;
/*
* 8 - restore cursor position.
*/
case '8':
x = savex;
y = savey;
break;
/*
* Received c. Reset terminal.
*/
case 'c':
break;
/*
* Received D. Active position down a line, scroll if at bottom margin.
*/
case 'D':
if(++y > yscrmax) {
y = yscrmax;
scroll(yscrmin+1, yscrmax+1, yscrmin, yscrmax);
}
break;
/*
* Received E. Active position to start of next line, scroll if at bottom margin.
*/
case 'E':
x = 0;
if(++y > yscrmax) {
y = yscrmax;
scroll(yscrmin+1, yscrmax+1, yscrmin, yscrmax);
}
break;
/*
* Received M. Active position up a line, scroll if at top margin..
*/
case 'M':
if(--y < yscrmin) {
y = yscrmin;
scroll(yscrmin, yscrmax, yscrmin+1, yscrmin);
}
break;
/*
* Z - Identification. The terminal
* emulator will return the response
* code for a generic VT100.
*/
case 'Z':
Ident:
sendnchars2(5, "\033[?6c");
break;
/*
* H - go home. (No, I think this sets a horizontal tab stop.)
*/
case 'H':
// x = y = 0;
break;
/*
* > - set numeric keypad mode on
*/
case '>':
break;
/*
* = - set numeric keypad mode off
*/
case '=':
break;
/*
* # - Takes a one-digit argument that
* we need to snarf away.
*/
case '#':
get_next_char();
break;
/*
* ( - switch G0 character set
*/
case '(':
g0set = get_next_char();
break;
/*
* - switch G1 character set
*/
case ')':
g1set = get_next_char();
break;
/*
* Received left bracket.
*/
case '[':
/*
* A semi-colon or ? delimits arguments. Only keep one
* previous argument (plus the current one) around.
*/
operand = number(buf);
prevOperand = 0;
while(buf[0] == ';' || buf[0] == '?'){
prevOperand = operand;
operand = number(buf);
}
/*
* do escape2 stuff
*/
switch(buf[0]){
/*
* c - same as ESC Z: who are you?
*/
case 'c':
goto Ident;
/*
* l - clear various options.
*/
case 'l':
break;
/*
* h - set various options.
*/
case 'h':
break;
/*
* A - cursor up.
*/
case 'A':
if(operand == 0)
operand = 1;
y -= operand;
if(y < 0)
y = 0;
olines -= operand;
if(olines < 0)
olines = 0;
break;
/*
* B - cursor down
*/
case 'B':
if(operand == 0)
operand = 1;
y += operand;
if(y > ymax)
y=ymax;
break;
/*
* C - cursor right.
*/
case 'C':
if(operand == 0)
operand = 1;
x += operand;
/*
* VT-100-UG says not to go past the
* right margin.
*/
if(x > xmax)
x=xmax;
break;
/*
* D - cursor left
*/
case 'D':
if(operand == 0)
operand = 1;
x -= operand;
if(x < 0)
x = 0;
break;
/*
* H and f - cursor motion. operand is the column
* and prevOperand is the row, origin 1.
*/
case 'H':
case 'f':
x = operand - 1;
if(x < 0)
x = 0;
if(x > xmax)
x = xmax;
y = prevOperand - 1;
if(y < 0)
y = 0;
if(y > ymax)
y = ymax;
break;
/*
* J - clear some or all of the display.
*/
case 'J':
switch (operand) {
/*
* operand 2: whole screen.
*/
case 2:
clear(Rpt(pt(0, 0), pt(xmax+1, ymax+1)));
break;
/*
* operand 1: start of screen to active position, inclusive.
*/
case 1:
clear(Rpt(pt(0, 0), pt(x, ymax+1)));
clear(Rpt(pt(0, y), pt(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)));
break;
}
break;
/*
* K - clear some or all of the line.
*/
case 'K':
switch (operand) {
/*
* operand 2: whole line.
*/
case 2:
clear(Rpt(pt(x, y), pt(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)));
break;
/*
* Default: active position to end of line, inclusive.
*/
default:
clear(Rpt(pt(x, y), pt(xmax+1, y+1)));
break;
}
break;
/*
* L - insert a line at cursor position
*/
case 'L':
scroll(y, yscrmax, y+1, y);
break;
/*
* M - delete a line at the cursor position
*/
case 'M':
scroll(y+1, yscrmax+1, y, yscrmax);
break;
/*
* m - change character attributes.
* Attributes are:
* 0 Attributes off
* 1 Bold or increased intensity
* 4 Underscore
* 5 Blink
* 7 Negative (reverse) image
*/
case 'm':
standout = operand;
break;
/*
* r - change scrolling region. prevOperand is
* min scrolling region and operand is max
* scrolling region.
*/
case 'r':
yscrmin = prevOperand-1;
yscrmax = operand-1;
if (yscrmax == 0)
yscrmax = ymax;
break;
/*
* Anything else we ignore for now...
*/
default:
break;
}
break;
/*
* Ignore other commands.
*/
default:
break;
}
break;
default: /* ordinary char */
if(isgraphics && gmap[(uchar) buf[0]])
buf[0] = gmap[(uchar) buf[0]];
/* line wrap */
if (x > xmax){
x = 0;
newline();
}
n = 1;
c = 0;
while (!cs->raw && host_avail() && x+n<=xmax && n<BUFS
&& (c = get_next_char())>=' ' && c<'\177') {
buf[n++] = c;
c = 0;
}
buf[n] = 0;
// clear(Rpt(pt(x,y), pt(x+n, y+1)));
drawstring(pt(x, y), buf, standout);
x += n;
peekc = c;
break;
}
}
}
^ permalink raw reply [flat|nested] 9+ messages in thread