AUSAM/source/ded/draw.c
#include "ded.h"
#include "char.h"
/* make the necessary movements on the screen */
draw(ch, chtype)
char ch;
int chtype;
{ register char c;
register int ctype;
char tail[ENOUGH];
int i;
int col, col1, col2;
int ntpos;
int fline;
c=ch; ctype=chtype;
do
{ switch (ctype)
{ case CONTROL:
case ONE:
case MODIFY:
case SPACE:
if (!roomfor(1, virt_c.row))
break;
else
{ copytail(tail);
show(c);
if (virt_c.col<rightcol)
{ virt_c.col++; showtail(tail); }
}
return;
case TWO:
if (!roomfor(2, virt_c.row))
break;
else
{ copytail(tail);
show(c_MODIFY); virt_c.col++;
show(unmodify(c));
if (virt_c.col<rightcol)
{ virt_c.col++; showtail(tail); }
}
return;
case TAB:
if ((ntpos = nextab(virt_c.col)) > BELLMARGIN);
/* complain();
* (too bloody loud)
*/
col = virt_c.col;
while ((rowmap[virt_c.row])[col]==c_SPACE && col<ntpos) col++;
if (!roomfor(ntpos-col, virt_c.row))
cdiag("!! no room on line !!");
else
{ virt_c.col = col;
if (virt_c.col != ntpos)
{ copytail(tail);
while (virt_c.col < ntpos)
{ show(c_SPACE); adj_virt_c(0,1); }
showtail(tail);
}
}
return;
case RUBOUT:
if (virt_c.col<=leftcol)
{ virt_c.col=leftcol;
if (mode==INMODE)
{ if (virt_c.row==toprow)
scrdown(SCROLL);
if (virt_c.row==toprow)
cdiag("!! top of file !!");
else
if (!roomfor(lastcol(virt_c.row)+2, virt_c.row-1))
cdiag("!! no room on line above !!");
else
{ copytail(tail);
fline = topl+virt_c.row;
del_row(virt_c.row, &virt_c);
virt_c.row = fline-topl-1;
position(virt_c.row, lastcol(virt_c.row)+2);
showtail(tail);
} /* shift line */
} /* mode==INMODE */
else complain(); /* edit mode bleep at left col */
}
else
{ copytail(tail);
virt_c.col--;
showtail(tail);
}
return;
case CERASE:
copytail(tail);
if (*tail == 0) complain();
else showtail(tail+1);
return;
case WRUBOUT:
if (virt_c.col<=leftcol) complain();
else
{ col = backword(virt_c.col);
copyrow(virt_c.row, virt_c.col, tail);
virt_c.col = col;
showtail(tail);
}
return;
case WERASE:
if (virt_c.col > lastpos(virt_c.row) ||
(mode==EDMODE && hit_diagnostic()) )
complain();
else
{ col = nextword(virt_c.col);
copyrow(virt_c.row,col,tail);
showtail(tail);
}
return;
case HEADERASE:
if (virt_c.col <= leftcol) { virt_c.col=leftcol; complain(); }
else
{ copytail(tail);
virt_c.col = leftcol;
showtail(tail);
}
return;
case TAILERASE:
if (lastcol(virt_c.row)<virt_c.col) complain();
else cleartail();
return;
default: editerror("invalid character type in draw %d",ctype);
}
/* come here (via 'break') when line is absolutely full
* - break line in two if possible
*/
col1 = sp_right(virt_c.col)+1;
col2 = sp_left(virt_c.col-1)+1;
if (txin && mode==INMODE &&
( (col1>BELLMARGIN && (col=col2)>0) ||
(col=col1)>0 ))
{ copyrow(virt_c.row, col, tail);
redraw(virt_c.row, col, " ");
ins_row(virt_c.row, tail, &virt_c.row);
if (col<virt_c.col)
{ virt_c.row++; virt_c.col =- col; }
continue;
}
else
{ cdiag("!! no room on line !!"); return; }
} while (true);
}
roomfor(num, srow)
int num, srow;
{ register char *sp;
register int n;
n=num;
sp = rowmap[srow]+rightcol;
while (n-- > 0) if (*sp-- != c_SPACE) return(false);
return(true);
}
show(c)
char c;
{ register char rc;
fixpos();
ttyout(rc=c);
(rowmap[real_c.row])[real_c.col] = rc;
if (++real_c.col >= ncols)
{ if (++real_c.row >= nrows) editerror("rolled off bottom of screen");
/* god only knows where it goes */
real_c.col = ncols*10; real_c.row = nrows*10;
}
}
showtail(s)
char *s;
{ redraw(virt_c.row, virt_c.col, s); }
copytail(tail)
char *tail;
{ copyrow(virt_c.row, virt_c.col, tail); }
/* in order to avoid too many characters, only draw those
* characters which have altered
*/
char blanks[] " ";
redraw(srow,scol,p_newrow)
int srow,scol;
char *p_newrow;
{ struct CURSOR tmp;
register char *oldrow, *newrow;
register char c;
char *oldrowlim;
store_c(&virt_c, &tmp);
if ((newrow=p_newrow) == 0) newrow = blanks;
oldrow = rowmap[srow]+scol;
oldrowlim = rowmap[srow]+(srow==FOOTROW ? ncols-2 : ncols-1);
virt_c.row = srow;
while (oldrow <= oldrowlim)
{ if ((c = *newrow++) != *oldrow++ || c==0)
{ if (c==0)
{ newrow = blanks; oldrow--; }
else
{ virt_c.col=oldrow-rowmap[srow]-1;
show(c);
}
}
}
store_c(&tmp,&virt_c);
}
cleartail()
{ redraw(virt_c.row, virt_c.col, blanks); }
backword(scol)
int scol;
{ register char *rp, *rplim;
rp = rowmap[virt_c.row] + scol;
rplim = rowmap[virt_c.row] + leftcol;
if (rp>rplim)
{ rp--; /* move back to previous character */
/* the next piece of nastiness moves back to the previous character
* if the cursor is pointing at a space
*/
if (rp>rplim && *rp ==c_SPACE && *--rp ==c_SPACE)
{ while (rp>rplim && *(rp-1) == c_SPACE) rp--; /* space sequence */
if (rp!=rplim) rp++; /* move one right except at lhs */
}
else
if (rp>rplim && alphmer(*rp)) /* word */
while (rp>rplim && alphmer(*(rp-1))) rp--;
/* it was punctuation - do nothing else */
}
return(rp-rowmap[virt_c.row]);
}
nextword(scol)
int scol;
{ register char *rp, *rplim;
if (mode==EDMODE && hit_diagnostic()) return(virt_c.col);
rp = rowmap[virt_c.row]+scol;
rplim = rowmap[virt_c.row] + rightcol;
if (rp<rplim && *rp==c_SPACE) /* space */
{ if (scol==0 || rp[-1] == c_SPACE)
while (rp<rplim && *rp==c_SPACE)
rp++; /* skip all the spaces in a sequence */
}
else
if (rp<rplim && alphmer(*rp)) /* word */
while (rp<rplim && alphmer(*rp)) rp++; /* skip word */
else /* punctuation */
if (rp<rplim) rp++;
/* whatever happens, skip space following */
if (rp<rplim && *rp==c_SPACE) rp++;
return(rp-rowmap[virt_c.row]);
}
int sp_right(scol)
int scol;
{ register int i;
register char *rp;
rp = rowmap[virt_c.row]+scol;
for (i=scol; i<=rightcol; i++)
if (*rp++ == c_SPACE) return(i);
return(-1);
}
int sp_left(scol)
int scol;
{ register int i;
register char *rp;
rp = rowmap[virt_c.row]+scol;
for (i=scol; i>=leftcol; i--)
if (*rp-- == c_SPACE) return(i);
return(-1);
}