#include "ded.h" #include "char.h" #include "ter.h" /************************************************************************ * * * copyright Richard Bornat 1981 * * * ************************************************************************/ /* Modified 27/2/84 to add overtype mode - PLS */ /* make the necessary movements on the screen */ draw(ch, chtype) register char ch; int chtype; { register int vrow, vcol; reswitch: vrow = virt_c.row; vcol = virt_c.col; switch (chtype) { case CONTROL: ch=c_CONTROL; case ONE: case MODIFY: case SPACE: if (overtype) over_char(ch); else { if (!roomfor(1, vrow)) break; else ins_char(ch, 0, 1); } return; case TWO: if (overtype) { over_char(c_MODIFY); if (!roomfor(1, vrow)) break; else ins_char((*ter.in_two)(ch), 0, 1); } else { if (!roomfor(2, vrow)) break; else ins_char(c_MODIFY, (*ter.in_two)(ch), 2); } return; case TAB: { int ntpos = nextab(vcol); int col = vcol; /* char *rp = rowmap[vrow]; always insert tabs UMIST */ /* while (rp[col]==c_SPACE && col lastcol(vrow)) join_next(vrow,vcol); else newtail(true, vcol,vcol+1); return; case WRUBOUT: if (vcol<=leftcol) join_prev(); else if (overtype) clear_zone(left_word(vcol), vcol); else newtail(false, left_word(vcol), vcol); return; case WERASE: if (vcol > lastcol(vrow)) join_next(vrow,vcol); else if (overtype) clear_zone(vcol, right_word(vcol)); else newtail(true, vcol, right_word(vcol)); return; case HEADRUBOUT: { int fc = firstcol(vrow); if (vcol<=leftcol) join_prev(); else if (overtype) if (fc>=vcol) virt_c.col = leftcol; else clear_zone(fc, vcol); else if (fc>=vcol) newtail(false, leftcol, vcol); else newtail(false, fc, vcol); return; } case TAILERASE: if (vcol > lastcol(vrow)) join_next(vrow,vcol); else cleartail(vrow,vcol); return; case LINEERASE: del_row(vrow); return; default: editerror("invalid character type in draw %d",chtype); } /* come here (via 'break') when line is absolutely full * - break line in two (always possible because of c_CONTROL) */ if (mode==INMODE && line_break(vcol, chtype)) { if (txin && (chtype==SPACE || chtype==TAB)) return; else goto reswitch; } else { cdiag("!! no room on line !!"); return; } } roomfor(num, srow) register int num; register int srow; { register char *sp = rowmap[srow]+rmargin(srow); if (rightcol-virt_c.col+1 0) if (*sp-- != c_SPACE) return(false); return(true); } /************************************************************************ * * * procedures to put a character on the screen * * * ************************************************************************/ /* put a character where the real cursor is */ display(c) register char c; { register int row = real_c.row, col = real_c.col; if (row<0 || row>FOOTROW || col<0 || col>=ncols || row==FOOTROW && col>=RIGHTCOL) return; /* refuse to draw the bottom right corner */ else { ttyout(c); (rowmap[row])[col] = c; if (++real_c.col >= ncols) { /* god only knows where it goes */ real_c.col = ncols*10; real_c.row = nrows*10; } } } redisplay(srow, scol, c) register int srow, scol; register char c; { if ((rowmap[srow])[scol] != c) { move_to(srow, scol); display(c); } } /************************************************************************ * * * insert one or more characters * * * ************************************************************************/ /* an all-purpose insert routine. Will insert one character c1 (n==1), * two characters c1 and c2 (n==2) or multiple copies of c1 (c1==c2, n>1). * This bizarre interface is determined by the needs of characters of classes * ONE (etc.), TWO and TAB. */ ins_char(c1, c2, n) char c1, c2; register int n; { t_ins_char(virt_c.row, virt_c.col, c1, c2, n); virt_c.col += n; } /************************************************************************ * * * overtype one or more characters - UMIST * * * ************************************************************************/ /* overtype character */ over_char(c) register char c; { if (virt_c.row == EDITROW) diag_clear(); redisplay(virt_c.row, virt_c.col, c); virt_c.col++; } /* clear characters without closing up line */ clear_zone(col1, col2) register int col1, col2; { virt_c.col = col1; while (col1 < col2) redisplay(virt_c.row, col1++, ' '); } /************************************************************************ * * * redraw - a central procedure in ded * * * * in order to avoid too many characters, only draw those * * characters which have altered * ************************************************************************/ redraw(srow,scol,newrow) int srow,scol; register char *newrow; { char *rm = rowmap[srow]; char *rmlim = rm+(srow==FOOTROW ? RIGHTCOL-1 : RIGHTCOL); register char *oldrow = rm+scol; register char c; if (newrow == 0) newrow = ""; while (oldrow <= rmlim) { if ((c = *oldrow++) != *newrow++) { if (*--newrow!=0 || c!=' ') { if (*newrow==0) { cleartail(srow, scol); return; } else { move_to(srow, scol); display(*newrow++); } } } scol++; } } /************************************************************************ * * * deleting one or more characters * * * ************************************************************************/ newtail(bleep,col1,col2) int bleep; register int col1,col2; { if ((virt_c.col = col1)>lastcol(virt_c.row)) { if (bleep) complain(); } else t_del_chars(virt_c.row, col1, col2); } /************************************************************************ * * * clearing head and tails of lines * * * ************************************************************************/ cleartail(r,c) { (*ter.clr_tail)(r,c); } /* not needed at present clearhead() { (*ter.clr_head)(virt_c.row, virt_c.col); virt_c.col=leftcol; } */